Tailwind CSS icons
The glyphfox Tailwind plugin turns every icon into a utility class. Icons render as a CSS mask filled with currentColor, so the text color, font size and opacity utilities you already use style them too.
Install
The plugin ships inside the main package as glyphfox/tailwind. Tailwind CSS is an optional peer dependency, and the same plugin works with Tailwind CSS v3 and v4.
npm install glyphfox
With Tailwind CSS v4, register the plugin in the stylesheet that imports Tailwind:
@import "tailwindcss"; @plugin "glyphfox/tailwind";
With Tailwind CSS v3, add it to the plugins array of your config file:
module.exports = {
content: ['./src/**/*.{html,js,jsx,ts,tsx,vue,svelte}'],
plugins: [require('glyphfox/tailwind')],
};Nothing else is needed: no font files, no sprite and no JavaScript in the browser. The plugin reads the icon data at build time and writes one CSS rule for every icon class it finds in your source files.
Your first icon classes
An icon class is the prefix gf- followed by the icon name. Put it on an empty inline element, usually a span. The class makes the element an inline block of 1em by 1em, aligns it with the text baseline and paints it with the current text color.
<button class="inline-flex items-center gap-2 text-sm text-zinc-200"> <span class="gf-download" aria-hidden="true"></span> Download </button> <span class="gf-home text-2xl text-orange-500" aria-hidden="true"></span> <span class="gf-heart text-4xl text-rose-500 opacity-80" aria-hidden="true"></span>
Because the box is 1em square, text size utilities size the icon: text-sm gives a 14 pixel icon, text-2xl a 24 pixel one. Inside a button the icon follows the button text with no extra classes, which keeps icon and label in proportion at every breakpoint.
Color comes from color, so text-* utilities, hover: and dark: variants and inherited colors all apply. Under the hood the icon is the background color of the element, set to currentColor and seen through a mask of the icon shape. That is why text color utilities color it and opacity-* fades it like any other element.
Every name from the icon browser works, for example arrow-right, settings or bell-ring. A class with a name that does not exist produces no CSS at all, so a typo shows up as an empty space rather than a broken style.
Styles, corners and weight after the slash
The three axes every glyphfox icon has are written after a slash, joined with dashes. Each combination is its own mask, rendered from the same geometry the components use.
<span class="gf-folder/solid"></span> <span class="gf-folder/duotone"></span> <span class="gf-search/sharp"></span> <span class="gf-search/w1.5"></span> <span class="gf-heart/duotone-sharp-w2.5"></span>
solidfills the closed shapes and cuts the inner lines out as negative space.duotonekeeps the outline and adds the second layer at its own opacity.outlineis the default.sharpswitches to miter joins and square caps;roundis the default.w1tow3set the stroke weight on the 24 grid, in steps as fine as you like:w1.5,w2.25.
A mask carries shape and transparency, not color. The duotone layer therefore shows as a lighter area of the same color, not as a second color. When you need two colors, render the icon as inline SVG with a component or toSvg and set secondaryColor.
Badges and fusions
The name syntax shared by every glyphfox package also works in classes: file+check adds a modifier badge, @tl, @tr, @bl or @br moves it to a corner, and cloud&lock fuses two or more icons into one. Tailwind CSS v4 only accepts + and & inside square brackets, so write these specs as arbitrary values:
<!-- Tailwind CSS v4 and v3 --> <span class="gf-[file+check]"></span> <span class="gf-[file+check]/tr"></span> <span class="gf-[cloud&lock]"></span> <span class="gf-[cloud&lock]/side"></span> <span class="gf-[shield&heart]/inside"></span> <!-- Tailwind CSS v4 also accepts the layout inside the brackets --> <span class="gf-[cloud&lock:side]"></span> <!-- Tailwind CSS v3 also accepts the short form --> <span class="gf-file+check"></span> <span class="gf-file+check/tr"></span>
After the slash, a corner token (tl, tr, bl, br) places the badge and a layout token (overlap, side, stack, grid, orbit, badge, inside) arranges a fusion. They combine with the axes: gf-[cloud&lock]/side-solid is a side by side fusion in the solid style.
In v3 every name+modifier pair is available in the short form out of the box. Fusions in the short form need to be listed with the combos option shown below; the bracket form needs no configuration in either version.
Animation classes
The plugin also adds six animation utilities: gf-spin, gf-pulse, gf-pop, gf-wiggle, gf-bounce and gf-shake. They use the same timing as the living states of the components. Spin and pulse loop; the others play once when the class is applied.
<span class="gf-loader-circle gf-spin text-xl" aria-hidden="true"></span> <span class="gf-bell gf-shake text-xl" aria-hidden="true"></span> <!-- replay on hover with a variant --> <span class="gf-heart text-xl hover:gf-pop" aria-hidden="true"></span>
These classes move the whole element with transform and opacity. They cannot trace strokes one by one, so there is no draw class, and they cannot morph one icon into another. For those, use inline SVG: the animated icons guide covers both. Every animation class switches itself off under prefers-reduced-motion: reduce.
Plugin options
The plugin takes six options. In Tailwind CSS v4 pass them in a block after @plugin; in v3 call the plugin as a function.
@import "tailwindcss"; @plugin "glyphfox/tailwind" { prefix: icon; variant: duotone; weight: 1.5; }
const glyphfox = require('glyphfox/tailwind'); module.exports = { content: ['./src/**/*.{html,js,jsx,ts,tsx}'], plugins: [ glyphfox({ prefix: 'icon', // icon-home, icon-spin size: '1.25em', // box size, 1em by default corners: 'sharp', // default axes for every class weight: 1.75, combos: ['cloud&lock', 'file+check@tr'], }), ], };
| Option | Default | Effect |
|---|---|---|
prefix | gf | Prefix of the icon classes and of the animation classes. |
size | 1em | Width and height of every icon box. Keep a relative unit so text utilities keep working. |
variant | outline | Default style; a token after the slash still overrides it. |
corners | round | Default corners. |
weight | 2 | Default stroke weight. |
combos | none | Extra specs exposed as short classes, such as cloud&lock; mostly useful in v3. |
Class reference
Classes replace props here. This is every token the plugin understands; the full name syntax is described in the docs.
| Class or token | Meaning | Example |
|---|---|---|
gf-NAME | an icon | gf-search |
gf-[NAME+MODIFIER] | a modifier badge: plus, minus, check, x, alert, lock, clock, sync, arrow-up, arrow-down, dot | gf-[user+plus] |
gf-[A&B] | a fusion of 2 to 10 icons | gf-[cloud&lock] |
/outline, /duotone, /solid | style axis | gf-star/solid |
/round, /sharp | corners axis | gf-square/sharp |
/w1 to /w3 | weight axis | gf-search/w1.5 |
/tl, /tr, /bl, /br | badge corner | gf-[file+check]/tl |
/overlap, /side, /stack, /grid, /orbit, /badge, /inside | fusion layout | gf-[cloud&lock]/side |
gf-spin, gf-pulse, gf-pop, gf-wiggle, gf-bounce, gf-shake | animation | gf-loader gf-spin |
Accessibility
A mask icon is an empty element with a background. Assistive technology sees nothing, which is right for a decorative icon next to a label: add aria-hidden="true" so the empty element is skipped. When the icon is the only content of a control, the control needs a name of its own:
<button type="button" class="p-2 text-zinc-300 hover:text-white"> <span class="gf-settings text-xl" aria-hidden="true"></span> <span class="sr-only">Settings</span> </button>
In Windows high contrast mode the browser replaces background colors with system colors, and a mask icon can disappear into the page. Give your icon spans a shared class and restore the color in that mode:
@media (forced-colors: active) { .icon { forced-color-adjust: none; background-color: CanvasText; } }
The accessibility guide covers labels, contrast and motion for every way of rendering glyphfox icons.
What it adds to your CSS
Tailwind generates rules only for the classes it finds in your files, and the plugin follows the same rule: an icon you never write costs nothing. Each icon class you do use embeds its mask as a small data URI, around 300 bytes for a simple shape such as home or file and close to 1 KB for a detailed one such as settings, before compression. Every style, weight or corner variant of the same icon is a separate rule with its own data URI.
For a page with a few dozen icons that is a few kilobytes of CSS and no requests at all. If you use hundreds of icons on every page, or many variants of each, compare with an SVG sprite, which the browser caches as one file.
Pitfalls
- Class names built from pieces
- Tailwind finds classes by scanning your files for complete strings.
`gf-${name}`never appears in full, so no CSS is generated. Map values to complete class names, such as{ saved: 'gf-[file+check]', error: 'gf-[file+alert]' }, or add the names you need to a safelist. - Plus and ampersand without brackets in v4
- In Tailwind CSS v4,
gf-file+checkandgf-cloud&lockare not valid class candidates and produce nothing. Usegf-[file+check]andgf-[cloud&lock], which work in both versions. - Width utilities fighting the icon size
- The icon class sets
widthandheightto thesizeoption. Asize-6orw-6on the same element sets the same properties, and which one wins depends on the order of the rules in the generated CSS. Size icons with text utilities, or change thesizeoption once. - Two colors
- A mask paints a single color.
/duotonegives a translucent second layer of the same color; for a real second color, render inline SVG withsecondaryColor. - Content inside the element
- The icon is the background of the element. Text or children inside it render on top of the icon, and a
bg-*utility replaces the icon color. Keep icon elements empty. - Animations on hidden elements
- A
gf-poporgf-shakeclass plays once when the element is rendered. If it is rendered while hidden, the animation finishes before anyone sees it. Add the class when the change happens, or use a component withtrigger="state".
Questions
Does the plugin work with Tailwind CSS v3 and v4?
Yes, it is the same plugin. In v4 register it with @plugin "glyphfox/tailwind" in your CSS and write badges and fusions in brackets; in v3 add require('glyphfox/tailwind') to plugins, where the short forms also work.
Can I use the icon classes in React, Vue or Svelte?
Yes. The classes are plain CSS, so they work in any template, including server rendered and static pages. Use the framework components instead when you need two colors, the draw animation, morphing or an accessible name on the icon itself.