Creating a Variable Font

  • by Rainer Erich Scheichelbauer
  • Tutorial

Welcome to Variable Fonts in Glyphs! This tutorial covers a workflow for recent versions of Glyphs. We recommend to install the latest beta version of the software. To do that, go to Glyphs > Preferences > Updates, activate both checkboxes you see in the dialog, and press the Check Now button. Keep in mind that, while Glyphs can export working Variable Fonts, the implementation is currently in beta. Throughout this tutorial, I will point out where you still have to be careful.

What are Variable Fonts?

If you have not read John Hudson’s excellent introductory article, stop right now what you are doing, and read it. No, really.

Step 1: Define Axes

In File > Font Info > Font, add a custom parameter called Axes. Double click its Value field. In the upcoming dialog, click on the gear buttons to add and remove axes. Pick one of the predefined axes (Weight, Width, Italic, Slant, Optical Size), or make up your own.

Pro tip: If you make up your own ‘private’ axis, you will also have to pick a four-letter tag. To avoid potential collision with updates of the standard, it is recommended to keep your private tag in all caps, e.g., SMIL for Smile or ROTN for Rotation. That is because all-caps tags are officially reserved for private use. Predefined axes will always be lowercase.

You can redefine your axes any time, and in the current implementation, you can define up to 6 axes. In this example, I will stick to one axis, Weight, with the tag wght:

You can manage your axes with the gear menu in the lower left corner of the dialog sheet.

Step 2: Set up Masters

In File > Font Info > Masters, add masters with the plus button in the lower left corner of the window, very much like you would for a Multiple Masters project. In our example, we will add two masters, Light and Bold.

For each master, pick the following settings:

  1. Make sure you pick an appropriate master name for each master. In our case, I would say Light and Bold are good guesses. The master names are not exported into the final font file. They are important for your own orientation when you work in Glyphs.
  2. Most importantly, set the axis coordinates for each master. In our example, set the Weight value, e.g., 50 for the Light Master, and 200 for the Bold Master. Many designers like to use the stem thickness as value for the weight axis value, but you can enter whatever you like, as long as the values are sufficiently different, so that Glyphs can calculate intermediate instances. In our example, we could calculate an instance at numbers between 50 and 200, e.g., 75, 120, 182, etc.
  3. Optionally, pick a master icon from the pop-up in the top right of the window. You can select from a range of lowercase n’s representing all sorts of weight and width combinations. You can also enter a glyph name at the bottom, and Glyphs will use an image of the respective glyph as master icon. Again, this is only for your orientation, so pick something that makes sense to you.

Of course, if you scroll down a little in the window, you will find many more settings: zones, stems, custom parameters. You should set them to whatever is appropriate for your design. Just make sure the entered values are compatible. That means that if you add a value in one master, you have to add a corresponding value in all other masters. E.g., if you have some standard stems in one master, the other masters must have the same count and order of stem values as well.

Beta note about axis coordinates: Technically, each axis has a definition of a scale with specific semantics. E.g. the Weight scale must be compatible with usWeightClass to work with CSS and allow switching between fonts while keeping the same relative style. Thus, 400 must be the Regular, and 700 must be the Bold, etc. The Width class must have 100 as the coordinate for the normal width, and the numbers for other masters must be the relative percentage of width vs the normal width, usually 75 for a Condensed, or 125 for an Extended.

Achieving this is a little tricky for the Weight axis in the current implementation. You may either use the spec-defined ranges instead of the stem width, or add Axis Location parameters (see below) to remap the masters. Both options have the downside that the predefined weights between your masters are unlikely to distribute as evenly as usWeightClass assumes. In other words, if you have a Regular master at 400 and an Extrabold master at 800, you are more likely to win the lottery than to have the luck that your Medium instance happens to fit perfectly on 500, the Semibold instance on 600, and the Bold instance at 700.

You could theoretically circumvent this by inserting your instances as masters. This is possible by going to File > Font Info > Instances, selecting one instance after another, and choosing Instance as Master from the Plus button in the bottom left corner of the window, and subsequently switching to the Masters tab of the same window, and resetting their Weight coordinates to usWeightClass numbers. Back in the Instances tab, you can then delete and reinsert the instances with the Add Instance for each Master option, again from that little Plus button.

For now, we recommend to do this only for a seriously shipping font, and not care too much about it while you are experimenting for yourself or for a specific implementation.

Step 3: Draw Compatible Glyphs

To keep it short and simple, we will stick to an uppercase A for this tutorial. I draw the light A with a stemwidth of approximately 50 units, and the bold A with a stem 200 units wide:

Most importantly, keep all your outlines, components and anchors compatible, just as you would in a Multiple Master setup.

Pro tip: You can check compatibility with View > Show Master Compatibility (Ctrl-Opt-Cmd-N), but as long as you do not have any instances defined (see step 4), Glyphs will tolerate outline incompatibility. In File > Font Info > Font, you can add a custom parameter called Enforce Compatibility Check, and Glyphs will connect masters even if there are no instances between them:

Step 4: Add Predefined Instances

Even though our font is variable, and we have an endless amount of instances already, we can still pick some spots in the design space and define them as instances for the font submenu. In File > Font Info > Instances, add as many of those predefined instances as you like. Simply add new instances with the plus button in the lower left, or Option-drag an existing instance entry in the left sidebar to duplicate it.

All you need to do in each instance is this:

  1. Set an appropriate Style Name: Light, Regular, Medium, Semibold, Bold, Extrabold in our example.
  2. Pick a Weight and Width class from the pop-up menu right below the Style Name. What is important is that the numbers next to the menus are in the right order, because this is how Adobe sorts its font menus. In our example, all fonts have the same Width (Medium/normal, 5), but ascending Weight classes (from Light to Extrabold: 300, 400, 500, 600, 700, 800). For in-between instances, you can also add weightClass and widthClass parameters with in-between numbers. Read more about it in the Naming tutorial.
  3. Pick a Style Linking. In the uprights, you leave these usually blank, only the Bold is the Bold of the Regular. And every italic is the Italic of its upright counterpart, e.g., Semibold Italic is the Italic of Semibold. Only the Italic instance is the Italic of Regular, and the Bold Italic is the Bold and Italic of Regular. Read more about it in the Naming tutorial.
  4. Pick appropriate design space coordinates for each of your axes. Read more about the distribution of weights in the Multiple Masters, part 3 tutorial.
  5. And I hate to break it to you, but many Custom Parameters do not work in an OTVar instance, especially all post-processing ones, like filters. If you have any of those in your instance, they will be blissfully ignored by the software. Why? Because they jeopardize outline compatibility.

Step 5: Export and Test Your Variable Font

Choose File > Export and click on the Variable Fonts tab:

If you have the latest Adobe Illustrator or Adobe Photoshop CC 2108, you can export into the Adobe Fonts folder, choose the font in the Character panel, and open the little slider pop-up to experiment with the Weight axis:

Alternatively, you can drop the font file in one of the amazing web pages that allow you to test fonts. My favorites are Roel Niesken’s great Wakamai Fondue, ABC Dinamo’s Font Gauntlet (which also lets you animate your variable font), and of course Laurence Penney’s Axis Praxis page:

Or, you install the mekkablue scripts and run Test > Variable Font Test HTML, which creates an HTML file next to the latest OTVar export, and opens the enclosing folder in Finder. So all you need to do is drag that into a browser:

Hint: As of this writing, your best guess as browser is the current Chrome or Safari, if you are running macOS High Sierra or later, or iOS 11 or later. Safari will not work on older OS versions. Firefox and Edge should work as well, but make sure you are running the very latest browser version.

If you do want to use a different or older browser, or test on an old OS version, take a look at the Axis Praxis blog: There, Laurence Penney explains where to download and how to set up the pre-release versions of all popular browsers. More and more browsers are adding support for Variable Fonts, or already support them, but you need to enable something somewhere. Laurence explains it all in his post.

Circumventing Bugs

Adobe’s OTVar implementation is buggy. So, if the font does not interpolate properly in Illustrator or Photoshop, it may not be your font’s fault. Symptoms vary, but may include glyphs staying static and not reacting to slider position changes at all, or ugly small kinks appearing during slider movements, e.g., like this:

If that happens, you can try to set different start points in your outlines. We found that this sometimes helps circumvent AI’s rendering bug. In any event, if you see that the same glitch does not appear in the web browsers, it’s not your font’s fault. And it is best to send your font file to Adobe support, alongside an AI file containing a simple test case.

Another annoying implementation bug is sitting deep in Apple’s renderer CoreText. Offsets of components are miscalculated if the LSB is changing. Watch how the a behaves correctly, while the a-umlaut shifts more than it is supposed to do:

This affects all environments that make use of CoreText rendering, which include pretty much all browsers on the Mac. In that case, the best you can do is make sure that all compounds are decomposed when you export. Best way to do this: Add a Decompose Components in Variable Font parameter to File > Font Info > Font > Custom Parameters. Needless to say, the resulting TTF will be much larger, and not fit for web use until Apple fixes the issue.

We reported the bug to Apple, but if you have a good case in your hands, please let Apple know as well.

Optional: Add a Virtual Master

Imagine you need an axis which only applies to some glyphs. Let’s say, the crossbar height, which is applicable to letters like A, E, F, H, but not S, D, J, O, etc., and not to any non-letters, like figures, punctuation and symbols. It would not make sense to draw a new master for all the font, would it? Rather, you would introduce an extra master only for those glyphs that have a crossbar. Well, for cases like these, we have something called a Virtual Master:

  1. In File > Font Info > Font, add a new axis to the Axes parameter. Since this is not one of the standard axes, names are arbitrary. In this example, I suggest the name Crossbar Height and the four-letter tag CRSB:

  2. In the same window tab, add a parameter called Virtual Masters, and give it the value of the the Light master for the Weight axis, 50 in our example, and a minimum value for the Crossbar Height, let’s say zero:

  3. Go through all masters in File > Font Info > Masters, and make sure the axis coordinate for Crossbar Height is not zero but, e.g., 100. The idea is that the values make sense semantically somehow. In our case, zero represents the lowest possible crossbar position, and 100 the highest possible position.

Now that the Virtual Master is set up, you can draw the low-crossbar version of each glyph that needs it:

  1. Open the glyph in Edit view.
  2. In the Layers palette, duplicate the Light layer with the Copy button.
  3. Rename the layer copy to {50, 0}, i.e., curly braces containing comma-separated design space coordinates for Weight (50 representing the Light master in our example) and Crossbar Height (0 representing the lowest crossbar position in our example).
  4. Now change the drawing to what the letter should look like with Crossbar Height zero:

Note: Unless you want to do some fine-tuning, you will not need to add a Brace layer for the bold master. In Variable Fonts the deltas (point movements) of the two axes compliment each other and can be added up to form the bold with the low crossbar.

That’s it. Now all you need to do is export, and try the font again in Illustrator, Axis Praxis or the Variable Font Test HTML script, et voilà: a second axis is available, for lowering the crossbar towards the baseline:

Effectively, we have added a second dimension to our design space. If you do that, it is advisable to keep the masters in a rectangular arrangement, or even better yet in a vertical or horizontal offset in respect to the origin master. In our example, the Bold master is horizontally offset towards the Light master (difference in the first coordinate only), and the master with the low crossbar is vertically offset (difference in second coordinate only). This way you have the most control because you can reach any point within the design space rectangle by simply adding the vertical and horizontal deltas you created by arranging your masters as described.

Optional: Origin

Only one set of outlines is stored in the font. Non-OTVar-capable software will only be able to display these ‘default outlines’. That default is usually your first master. You can pick a different default, though. To do so, go to File > Font Info > Font and add a custom parameter called Variable Font Origin. As its value, pick the name of a master:

Yes, it must be a master. If you want any of your instances to be the origin, you would need to add the instance as an additional master: In File > Font Info > Instances, select the instance you want to define as your origin, open the Plus button in the lower left corner of the window, and pick Instance as Master from the pop-up menu that comes up. Now you have an additional master in File > Font Info > Masters, and you can set that as your Variable Font Origin.

Two things to consider:

  1. Default Appearance: One of the founding ideas behind variable fonts is that you can pick your most used instance as the default, typically the Regular. In Multiple Masters, you designed the extremes of the design space (i.e., your least used instances) and would interpolate everything in between. A variable font can go the opposite direction: it only stores the most important outlines, somewhere in the middle of the design space, and all other instances are derived from that one. So, for desktop fonts, pick the Regular as origin, or whatever the user will expect as the ‘default appearance’ of your font family. If all else fails, this is the weight the user will still be able to use.

  2. File Size: Picking a middle master will likely increase the number of your point deltas, and therefore, also increase the eventual file size. On a single-axis setup, it will likely double the number of deltas, if not more. In other words, for webfonts, it makes more sense to pick one of the masters in an extreme end of the design space, because you want to keep file sizes and load times down.

Optional: Axis Location

In File > Font Info > Masters, you can add a parameter called Axis Location. With it you can change the master’s coordinate on the axis. This makes sense if you need different values to be exposed to the users than the interpolation values entered in masters and instances.

In our example, you could argue that a slider going from 50 to 200 may confuse the users of your font. Therefore you want all your sliders to go from 0 to 100, like a percentage. So you will add Axis Location parameters to both masters: Weight 0 for the Light Master, Weight 100 for the Bold Master.

Note: If you add Axis Location parameters, you are effectively changing the axes exported into your variable font. That means you also have to adapt the coordinates of the affected axis in the Virtual Master parameter, if you have one. However, do not change the numbers in Brace and Bracket layers, because those still adhere to the design space created by the original interpolation values.


Some things you may have gotten used to, do not work quite as you may expect them to in a variable font.

  1. I briefly mentioned above that all post-processing with custom parameters in File > Font Info > Instances is ignored because they are too likely to break outline compatibility or glyph set consistency. That includes filters and the Rename parameters.
  2. Corner components work unless they break outline compatibility. But they work differently: in variable fonts, they are applied before interpolation, whereas in a classic Multiple Master setup, they are inserted afterwards.
  3. Both Brace and Bracket layers work, but not both within the same glyph. You can have glyphs with Brace layers and other glyphs with Bracket layers in your font, but not a glyph with both Bracket and Brace layers. Sorry about that, we’re working on it.

Not really optional: STAT Table

In new fonts, including all Variable Fonts, naming info is stored in the STAT table. STAT is short for Style Attributes, and includes, among other things, information about axes, instances, and something called the display strings, or name strings: These are names for sections on an axis. E.g. a weight axis may be sectioned into Light, Regular, Medium, Semibold, Bold; a width axis into Condensed, Regular, Extended.

The idea behind this is that an application can name a user’s current instance, no matter what his or her slider settings are. Effectively, in a multiple-axis setup, you get n-dimensional fields of possible names. E.g., if your font has a weight and a width axis, you get columns of weights, and rows of widths, like in the table below. And in order to name the combination of a weight in the Bold section with a width in the Condensed section, an application can simply combine the display strings, and ta-daaa, we have ‘Bold Condensed’:

A display string is deemed elidable if it is left out when combined with other display strings. Usually this is the case for default-style names like ‘Regular’, ‘Normal’, or the like. The semibold weight combined with regular width is usually just called ‘Semibold’, not ‘Semibold Regular’; or the normal weight in combination with the italic style is simply called ‘Italic’, not ‘Regular Italic’. Thus, the display name ‘Regular’ is considered elidable.

Usually, Glyphs takes care of this pretty smartly by analysing the names of your predefined instances. If however, you find that in the STAT table entries, the display strings are not properly stored in the file, you can take control with these two parameters in File > Font Info > Instances:

  • Style Name as STAT entry: Takes the instance style name as combinable display string for an axis range. As value, use the four-letter axis tag to which the display string applies. Use this only in instances that are non-normal on one axis and normal on all others. That is because the normal attributes have elidable names and do not appear in the style name (e.g., ‘Semibold’ or ‘Condensed’). Example: In the Light instance, use this parameter with the value wght, because Light is a value on the weight axis.

  • Elidable STAT Axis Value Name: Declares the instance style name as elidable for the axis specified in the parameter value. As value, use the four-letter tag of the respective axis. Typically, you will add this parameter in the regular style, and you will add one for each axis for which the name is an elidable display string. Example: An instance called Regular has two Elidable… parameters, one with wght and one with wdth as parameter values.

Pro tip: The STAT table is becoming increasingly important. In the not-so-distant future, many applications will require one for the font to load in the first place. Don’t ask me where I have picked it up, but let me tell you that if you want to ship (or keep shipping) fonts for Windows, you want to equip all your fonts with STAT. Hint, hint: This will include the Italic (ital) axis for differentiating between Uprights (value 0) and Italics (value 1).

Additional resources

Want to dig deeper and know more about Variable Fonts? We have a few links for you:

STAT table sample font: Plantago by Viktor Solt-Bittner and Schriftlabor.
Many thanks to Rob McKaughan for his commentary and advice on this tutorial.

Update 2018-03-16: Corrected some typos (thx Jeff Kellem).
Update 2018-06-22: Clarified wording for the example values (thx Karl).
Update 2018-11-20: Updated naming of Variable Font Origin parameter.
Update 2019-02-15: Added links for Font Gauntlet and Wakamai Fondue. Updated test script and browser support info. Added Circumventing Bugs.
Update 2019-03-13: Added Additional resources.
Update 2019-03-04: Corrected typos and replaced Variation Fonts by Variable Fonts of the Export window (thx Nathalie Dumont).
Update 2019-03-20: Corrected typos, replaced Add Instance as Master for Instance as Master, and modified link to Nick Sherman's V-Fonts (thx Nathalie Dumont).