Creating a variable font

Tutorial
by Rainer Erich Scheichelbauer

16 October 2023 Published on 8 March 2018

Variable fonts open a whole new world of possibilities. Creating them is a breeze in Glyphs.

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.

Done? Okay. So let’s set up a variable font in Glyphs, step by step. Here we go:

Step 1 Define axes

If we want to interpolate, we first need to set up a design space. The design space is a coordinate system defined by axes, much like the Cartesian coordinate systems we know from high school. Just that, instead of x, y, z axes, we have design axes that make sense for typography, such as Weight, Width, Slant, etc.

So, we go to File > Font Info > Font > Axes, and add an axis by clicking on the plus button:

Adding an axis
Choose File > Font Info, then, in the Font tab, click on the plus icon next to Axes, and a new design axis will be added.

In the axis entry that appears, pick the kind of axis that you would like. You can take any of the official ‘registered’ axes: Weight, Width, Italic, Slant, Optical Size, and a range of proposed new axes. Or, you can make up your own ‘private’ axis.

You can add almost any number of axes, each of them must have a unique four-letter axis tag. In this example, I will stick to one ‘registered’ axis, Weight, with the predefined tag wght.

Step 2 Set up masters

In the same File > Font Info window, switch to the Masters tab, and add masters with the plus button in the lower left corner of the window, or duplicate existing masters, 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. Most importantly, set the axes 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.

  2. 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.

  3. Optionally, pick a master icon from the Icon pop-up in the General section of each master. 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.

Okay, now we have the masters set up, we can add drawings in each master. Here we go.

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 (Cmd-1) with a stem width of approximately 50 units:

… and the bold A (Cmd-2) with a stem 200 units wide:

Add anchors by choosing Glyph > Set Anchors (Cmd-U) or even better, holding down the Option key, Glyph > Set Anchors for All Masters (Cmd-Opt-U). Most importantly, keep all your outlines and anchors compatible between both masters, just as you would in a Multiple Master setup.

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 > Exports, 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:

Setting up the instances
  1. Set an appropriate Style Name: e.g., Light, Regular, Medium, Semibold, Bold, Extrabold in our example.
  2. Optional: you can pick a Weight and Width Class from the pop-up menu right below the Name. The downside: this will only apply to the correlating static font exports, and not be written into the variable font. Read more about it in the Naming tutorial.
  3. Pick appropriate design space coordinates for each of your axes. Read more about the distribution of weights in the Multiple Masters, part 3 tutorial.
  4. 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.
  5. And I hate to break it to you, but most custom parameters do not work in an OTVar instance, especially ones that do shape post-processing, like most filters. If you have any of those in your instance, they will be blissfully ignored by the software. Why? Because they jeopardize outline compatibility.
  1. Optional: pick a Variable Style Name to override the (style) name of the instance. If you are using the same instances for both static and variable font exports, and for whatever reason, you are using different style names for static and variable styles, you can specifically set the variable style name with this property in the General section.

Step 5 Add a variable font setting

OK, so many custom parameters in instances do not work. For example, of course you cannot have different glyph sets in different instances of the same variable font, duh. Makes sense because a glyph cannot (and should not) just disappear or reappear when you move your sliders. That is why Export Glyphs and Remove Glyphs parameters are ignored in the instances. And you will find similar logical reasons for other parameters.

But what if we could apply parameters to the whole variable font? Well, we can. From the same plus menu in the lower left corner, add a Variable Font Setting:

… and define all the things you want to define, even glyph subsetting with the Keep Glyphs parameter, or changing the OpenType features and classes with the respective parameters, o, etc.

In Glyphs 3.1 and later, here is our recommendation:

  • Name: Call it Italic if the entire font is italic. Otherwise call it Regular. This will ensure style linking works even if romans and italics are in different files.
  • Family Name: Must be different from the static family name if you plan to ship both static and variable fonts. That is because a user could install both and have a font conflict. Typically, you will use the same family name with an extra signifier like ‘VF’ or ‘Var’ or ‘Variable’, for example: ‘Myfont VF’. If you have uprights and italics in different files, this entry must be the same in both files.
  • VariationsPostScriptNamePrefix: optional. Setting for name ID 25, and Glyphs will derive the fvar postScriptNameID entries from it as well. This is a PS name, so just use A-Z, a-z and 0-9, but no spaces or symbols or non-ASCII characters. If you have uprights and italics in different files, this entry must be different, e.g., ‘MyfontVarRoman’ and ‘MyfontVarItalic’.
  • Optional custom parameters: The variable font setting will provide you with all possible custom parameters when you click on the plus button. Consider fileName and Variable Font Origin.

Keep in mind: You can have multiple variable font settings, for exporting more than one variable font at the same time.

Step 6 Export and test your variable font

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

If you have the latest Adobe Illustrator, Adobe Photoshop (CC 2108 or later), or InDesign (CC 2020 or later), 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:

Circumvent 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.

Update: In recent CC versions, these rendering issues have become very rare. Actually, we have not seen any of these in CC 2021.

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 composites 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.

Update: Apple fixed the problem. Make sure you have the latest dot update of macOS 10.13, or a newer macOS.

Another bug in Apple’s rendering: The Optical Size axis (opsz) is misinterpreted in Safari. At the slider position that coincides with the origin master (i.e. the first master unless you specify a different Variable Font Origin with the custom parameter of the same name), it shows the rendering for the maximum value. This only appears in Safari, not in other browsers. Again, please let Apple know. Update: There is a feedback for this bug with ID FB6055886 filed. Make sure you reference it if you file another bug.

Then, there is a rendering problem that is caused by the fact that variable fonts keep their overlaps. Not really a bug, but it may appear to your users as such. If the edge of a shape is drawn by two (partially) overlapping path segments, anti-aliasing will cause the edge to appear darker than the ‘clean’ edges that are drawn only by one outline:

The only solution for this is to rewire your outlines in such a way that the outer edge of your shape is always ‘clean’, i.e., drawn by only one path at any given spot. E.g. like this:

In the very most cases, you will be able to fix this by removing overlaps and subsequently opening corners or reconnecting nodes. Both functions, Open Corner and Reconnect Nodes are available in the context menu of a respective point selection: individual corner nodes for opening corners, and pairs of corner nodes for reconnecting.

The mekkablue script Paths > Rewire Fire helps you find nodes that need to be reconnected. It cannot find everything, but usually most of the cases that cause unclean edges like the ones shown above. What you want is the option that finds ‘nodes on top of line segments’:

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 Master, 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. You can edit all of them at once if you select all the masters:

Now that the virtual master is set up in Font Info, 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 plus button. It will create backup layer carrying the current date and time as name.

  3. Right click the backup layer and turn it into an intermediate layer by choosing Layer Type > Intermediate Layer from the context menu:

  4. Double click the intermediate layer, and in the pop-up dialog that appears, set its 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):

  5. Now change the drawing to what the letter should look like with Crossbar Height zero:

Now the cool thing is: unless you want to do 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. So the best strategy may be to see if it works with just one master, and only add additional ones if the result is not good enough.

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: setting a different 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 or to a Variable Font Setting in File > Font Info > Exports and add a custom parameter called Variable Font Origin. As its value, pick the name of a master from the pop-up menu:

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 > Exports, 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.

What works and what does not

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 > Exports is ignored because they are too likely to break outline compatibility or glyph set consistency. That includes filters and the Rename parameters.
  2. Corner and segment components work. But they work differently: in variable fonts, Glyphs applies them before interpolation, whereas in a classic Multiple Master setup, they are inserted and adjusted afterwards. So, the result may be a little different between static and variable instances.
  3. Both intermediate and alternate layers work.
  4. Alternate layers do not translate into composites. There is a script solution for that though. See further below. Update: it should work in Glyphs 3.1 and later.
  5. Brushes work, as long as they are applied the same way in all masters.
  6. Path attributes like strokes do not work currently. The translation into TrueType curves would break outline compatibility.

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 analyzing 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 > Exports:

  • 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.

Axis mappings and locations

One more thing about axes. Obviously, axes start somewhere and end somewhere. In a user interface, the beginning and end of an axis can be (and usually are) represented by the leftmost and rightmost positions on a slider. Everything in between, of course, is spread out evenly between these extremes. In other words, in order to display 25% of the interpolation, you put the slider at the quarter position, for 50% of the interpolation, you put it exactly in the middle, and so on. Makes sense, doesn’t it?

Wait a minute. Does it really? Giving it more thought, it really only makes sense if the instances that the user should be able to access are also spread out (more or less) evenly across the complete slider range. For the sake of the argument, let’s imagine a situation where the important positions are crammed in a small part of the slider range, and a large part of the slider is not doing much for the user.

This actually happens to be the case for the Weight axis (axis tag wght). In (almost all) weight interpolations, the various weight styles are not distributed evenly. Depending on how thin the lightest master is and how fat the boldest, you will have more styles grouped together at different ‘focal points’ along the axis. For instance, interpolating from very thin to a ‘normal’, not-too-extreme bold will have styles concentrated towards the light end of the slider:

Why? Because in principle, equidistant movements of the slider correspond to the same changes in units, no matter where on the slider you make the movement. E.g., a certain back-and-forth here changes the design by 10 units, and the same back-and-forth there also changes by 10 units. However, adding 10 units to the stem thickness is a lot for a Hairline, which has only a few units to start with. But the exact same amount is practically negligible for a Medium or Semibold, because in comparison to the stem thickness, it is just a small change.

It is the other way around, if you go from a not-too-extreme Light or Book or Regular on one end towards a very bold Ultra Heavy on the other end of the slider. Now, the styles gather at the bold end of the spectrum:

How is that possible? Well, actually it is the reverse situation to the above, because what changes this time is the white in the letters. For a very, very heavy design, adding or removing 10 units to the white is a lot because there is so little white left. Yet, in the ‘normal’ range of weights between the average Book and Semibold designs, we still have the same situation: the styles are further apart.

Putting one and one together, it is now clear that interpolating from very thin to very bold usually has style concentrations towards both ends of the spectrum:

But on the other hand, the users do not care about our distribution problems, do they? For the users, accessing the different styles works best if they are distributed evenly across the axis, like this:

In other words, we need to somehow translate the evenly distributed user-accessible positions (‘external coordinates’) to the appropriately distributed design positions (‘internal coordinates’), like this:

This is called an axis mapping. We map what the user sees on the axis, to what the user actually gets on the axis. There are these conventions we are expected to fulfill:

  • Weight axis: external coordinates for the wght axis are expected to match the usWeightClass numbers. Minimum value is 1, maximum value is 1000. The higher the value, the bolder the font. Expected external coordinates are: 100 Thin, 200 Extralight, 300 Light, 400 Regular, 500 Medium, 600 Semibold, 700 Bold, 800 Extrabold, 900 Black. If you need something lighter than Hairline, use 1, the minimum. If you need something bolder than Black, use the maximum, 1000. There are no prescribed names for those extra weights, but I have seen ‘Laser’ and ‘Hairline’ for the very lightest weights, and ‘Extrablack’ and ‘Superheavy’ for the boldest of the bold. (spec)
  • Width axis: external coordinates for the wdth axis are expected to match the percentages described in the usWidthClass specification. The default letter width perceived as a ‘normal’ width is assumed to be at 100. More condensed designs will have a smaller value, wider letters will have a higher value, roughly indicating the percentage of line length in relation to the default width. In other words, wdth=50 means that the font is so condensed that it takes up only approximately half the space it needs at wdth=100. At wdth=200, the text would need approximately twice the space. (spec)
  • Italic axis: external coordinates for ital are assumed at 0 for upright/roman, 1 for italic. Note that you can interpolate between 0 and 1. (spec)
  • Slant axis: external coordinates should roughly reflect the counter-clockwise slant angle in degrees, ranging (theoretically) from −90 to +90. Yeah right, I want to see a design with an angle of 90°... but you get the idea. And the math buffs among you will note that the angles are not linearly distributed between the min and max slider positions, but well, it is good enough for non-technical people. Attention: the degrees are measured counter-clockwise, so a 10° slant angle would need to be specified as -10, no kidding. And, if you plan to interpolate between what you consider the upright and the italic, and you want your users to toggle between them with the Italic button, forget the Slant axis and use the Italic axis instead. (spec)
  • Optical size axis: external coordinates for opsz are simply the type sizes in points, at an average reading distance (40 cm). A regular size is thus assumed at 10–16 points, and the opsz value cannot ever be zero or negative. (spec)

All other axes, and of course custom axes, do not have expected values. In such a case, put yourself into the position of your users, and pick external coordinates that would make sense to you as a user of your own typeface. Sometimes, there is an agreed inofficial convention, though. So perhaps it is a good idea to ask in the forum what is the best course of action if you are being created with axes.

Whatever axis we pick, we can achieve a mapping for it through two methods: the Axis Mappings parameter, or through a setup of Axis Location parameters. Axis Mappings work well in single-axis setups. When you start having multiple dimensions, Axis Location parameters are definitely easier to handle and more precise. If you ask us, we will recommend Axis Location parameters to you.

Option 1 Axis Location parameters

With Axis Location parameters, you can exactly define the external coordinates for each master and instance. Glyphs will take this information and calculate the distributions for each axis. You will need to add the parameters in two places:

  1. In File > Font Info > Masters, add an Axis Location parameter for each master. You can select all masters, and add the parameter to all of them at once. You will still have to step through them and adjust each external coordinate manually.

  2. In File > Font Info > Exports, add an Axis Location parameter for each instance. Again, you can batch-add the parameter to all instances at once, exactly as with the masters. The external coordinates of the instances must be within the range of the masters, of course. And if an instance shares internal coordinates with a master, they also must share the same external coordinates. Makes sense, but it needs to be said.

That’s it, nothing else to be done. Next time you export your variable font, the font will have the desired (external) axis distribution for the user. Cool.

Of course, if you have many masters and many instances, it is tedious to edit all the Axis Location settings, ugh. That is where some useful scripts come in. See further below.

Note: If you are switching shapes, do not change the numbers in Brace and Bracket layers, or in the condition statement in your feature code. Those still adhere to internal interpolation values.

Option 2 Axis Mappings parameter

We can also achieve such a mapping with an Axis Mappings parameter plus Axis Location parameters for the masters. But how do we set it up? Easy:

  1. For each master in Font Info > Masters, add Axis Location parameters with appropriate external coordinates. You can skip the step if your external coordinates are the same as the internal coordinates. In our case, we cannot, simply because internal coordinate 50 should match external coordinate 300 (usWeightClass for Light).
  2. Add the Axis Mappings parameter in Font Info > Font.
  3. Click the parameter’s value to edit it. Add new values for each weight on your wght axis, each width on your wdth axis, etc. You can add a value by clicking the plus button at the bottom, or by clicking on a segment in the graphic next to it:
  4. The left column (or horizontal axis in the UI) represents the internal coordinates, make sure you match at least the instances you have set up. You can be more detailed though. The right column (or vertical axis in the UI) represents the external coordinates. Those should match the conventions described above.

In our example, the Axis Mappings may end up looking like this:

Testing axis distributions

Usually, axis mappings will only create subtle changes to the way your font behaves when you drag the slider from one end to the other. So, it will be hard to verify if everything worked out the way you intended it to be. Therefore we need a special tool to inspect the avar table. Luckily, Laurence Penney’s Samsa is such a tool: drag the font onto the page, and in the Axes inspector, turn on the Show avar option:

And then drag the slider to see the green arrow that indicates how the visible slider position (top) maps to the actual design distribution (bottom). You can get geeky extra information if you hover over the visualization and wait for the tooltip to pop up:

To explain, the avar values go between −1.0, 0.0 and +1.0. Glyphs will usually put your interpolation between 0.0 and +1.0. In other words, in avar, your light master will correspond to 0.0, and your bold master to +1.0. For instance, the tooltip pictured above says that the current slider position 550.4 (at 0.562988... or 56.3%) to the actual design position 540.38 (at 0.550476… or 55%), halfway between Medium (500) and Semibold (600).

Useful scripts

In the mekkablue scripts collection (link includes readme with installation instructions), you will find a number of useful scripts for making your variable font work:

  1. Interpolation > Composite Variabler: Reduplicates alternate layers of components in the composites in which they are used. Makes brace layers work in composites too. E.g., if you have a lowercase g with a brace layer that switches from a double- to a single-story design as it gets bolder, you need to reduplicate the bracket layer in the composites gcircumflex, gcommaaccent and gbreve. You will still need to decompose the bracket layers after running the script:

    Update: Composite Variabler should not be necessary anymore in Glyphs 3. Use this only as an emergency hack to fix things.

  2. Kerning > Zero Kerner: Adds group kernings with value zero for pairs that are missing in one master but present in others. Helps preserve interpolatable kerning in OTVar exports. Use this if you find that some kerning goes missing, especially kern pairings that only exist in some masters.

    Update: Zero Kerner should not be necessary anymore in Glyphs 2.6.5, builds 1300 and above.

  1. Interpolation > Set Weight Axis Locations in Instances: Will attempt to set Axis Location parameters for all instances according to their weight class (e.g., 600 for Semibold). If a master coincides with an instance, and does not have an axis location assigned, it will receive the same axis location as the instance. (The same functionality is baked into the Insert Instances script.) Hidden extra: if there are width classes set in the instances, and no axis location available for the width axis yet, it will attempt to populate width axis locations as well.

  2. Interpolation > Axis Location Setter: Will (re)set internal and/or external coordinates in instances and masters, based on the style name. E.g., all instances containing the name ‘Semibold’ (including Condensed Semibold Italic, Wide Semibold, etc.) should have internal weight axis coordinate 140, and external axis location 600. Useful for batch-moving instances in a multi-axis setup.

  3. Interpolation > Instance Cooker: Batch-create all instances from predefined locations for each axis. Very useful if you have many axes and need to create many instances. Description in the UI:

  1. Font Info > OTVAR Maker: Helps (batch) create variable font settings in File > Font Info > Export.

  2. Post Production > Fix Italic PS Names (OTVAR): If you run this after export of an italic variable font, the script will fix the postScriptNameID entries in the exported fvar table. Specifically it fixes ‘Italic’ double namings, i.e., it will turn MyfontItalic-MediumItalic into the suggested MyfontItalic-Medium. It outputs its progress in the Macro Window.

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).
Update 2019-10-23: added Useful Scripts.
Update 2019-12-04: added section about the anti-aliasing problem.
Update 2020-03-08: added paragraph about Safari opsz bug, the hint about the Rewire Fire script, and Samsa to the resources.
Update 2020-06-14: added Axis Mappings chapter, updated Useful scripts, added a GIF for the Safari opsz bug.
Update 2020-07-09: minor change of phrase in the paragraph about the Rewire Fire script.
Update 2020-11-17: partial adaptation for Glyphs 3.
Update 2020-12-14: largest part and screenshots updated for Glyphs 3.
Update 2022-04-19: rewrote ‘Axis mappings and locations’ (removed separate ‘Optional: axis location’ chapter). Added new useful scripts for axis locations.
Update 2023-10-16: added suggestions for variable font settings and two new scripts, updated Font Gauntlet link.
Update 2023-12-02: better explanation of the Safari opsz bug, added Apple Feedback ID.