Creating a Material Icons subset
Asked Answered
C

2

5

I'm only using a few Material Icons icons, and thought that loading the entire library is a waste of resources.

I tried to edit the original woff2 file and remove all icons that I don't use. The closest I got is using this tool: http://fontstore.baidu.com/static/editor/index-en.html#

But when I export the modified file, it doesn't work like the original one. This HTML for example doesn't render as an icon: <span class="material-icons">check_circle</span>

I added the needed CSS rules as instructed in Google's guide. Everything works when I self-host the original woff2, file but breaks when I modify it. It only works if using pseudo-elements with Unicode as the contnet. It seems like saving the file strips the mapping of names to icons (if it makes any sense, as I'm not familiar with how woff2 files work).

Is there a way to create a subset of the woff2 file that works like the original?

Cannonade answered 30/10, 2020 at 19:22 Comment(1)
Just to add my two cents after a frustrating afternoon, that font relies on ligatures. If you inspect the TTF version of the font, for example using fontdrop.info, you'll notice a lot of ligature definitions. Subsetting must preserve those ligatures. So far I'm unable to do that as well.Skirling
C
5

Here is a working example that subsets the thumb_up and thumb_down glyphs and ligatures.

  fonttools subset MaterialIcons-Regular.ttf \
    --unicodes=5f-7a,30-39,e8db,e8dc \
    --no-layout-closure \
    --output-file=o.woff2 \
    --flavor=woff2

What this says is:

  • --unicodes=5f-7a: include the glyphs for _, the letters a-z and the digits 0-9. From what I understand, the font cannot recognize thumb_alt as a ligature unless the individual glyphs t, h, u, ... are defined (even though we will never ask the font to render an individual letter glyph).
  • ...e8db,e8dc: specify the glyphs you actually need in your subset.
  • --no-layout-closure: include only the ligatures for the glyphs we need (thumbs_up and thumbs_down), not any other ligatures that can be constructed from the set _a-z, like add, delete, face and so on. Without this option, the subset grows to pretty much the whole set.

You can inspect the resulting file, for example on fontdrop.info, and it will show 30 glyphs and two ligatures. You can use the file as documented in the guide, in my case:

@font-face {
  font-family: 'Material Icons';
  font-style: normal;
  font-weight: 400;
  src: url('../../fonts/o.woff2') format('woff2');
}

.material-icons {
  font-family: 'Material Icons';
  font-weight: normal;
  font-style: normal;
  font-size: 24px;  /* Preferred icon size */
  display: inline-block;
  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';
}

To find the Unicode values of the glyphs you need, you can look at the codepoints file.

Cletus answered 17/2, 2021 at 8:53 Comment(1)
Very helpful! But Fontdrop can't show woff2 files, I use Font Forge instead. Switch to the compact view in the settings to only see the existing glyphs.Evaginate
V
1

I think subset-iconfont might meet your needs. The purpose of this package is to subset from several icon font packages and use the latest fontawesome css/scss styles. For your purpose, you can do it in a few lines:

npm install --save-dev subset-iconfont material-icons @material-design-icons/svg

then


import { MiProvider} from 'subset-iconfont';

const mi = new MiProvider(['alarm-on'], {
  formats: ['ttf', 'woff2'],
});

fa.makeFonts('./outputDir').then((result) => {
  console.log('Done!');
});

result of the demo

Then in folder ./outputDir find the result, open the generated index.html to see how to use it. As you might find, it will subset all the styles available of a single icons. That's why you'll get multiple font files in the webfonts direcory.

Besides, you can only keep the font files if you don't need the css/scss stuff.

P.S., I'm the author of the package.

Viceregal answered 29/6, 2022 at 10:34 Comment(1)
does subset-iconfont still support Google Material Icons? I just tried that with no success. Error generating fonts: hb_subset_or_fail returned zero, indicating failure. Maybe the input file is corrupted? Ensure the icons are valid and the font file is not corrupted. node:internal/process/promises:279Particle

© 2022 - 2024 — McMap. All rights reserved.