Frameworks

Ícones em HTML puro via CDN

Uma única tag script dá à página todos os ícones do glyphfox, o elemento <glyph-fox> e um runtime que transforma placeholders <i data-glyph> em SVG inline. Sem etapa de build e sem framework.

Adicione o script

O build em arquivo único traz todos os ícones, o elemento, o runtime de placeholders e o motor. Tanto o jsDelivr quanto o unpkg resolvem a URL simples do pacote para esse arquivo, dist/web/glyphfox.min.js.

index.html
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>My page</title>
  <script defer src="https://cdn.jsdelivr.net/npm/glyphfox@1"></script>
  <!-- or https://unpkg.com/glyphfox@1 -->
</head>
<body>
  <glyph-fox name="home"></glyph-fox>
  <i data-glyph="search" data-size="20"></i>
</body>
</html>

Com defer, o download não bloqueia a análise do HTML. O script roda assim que o documento termina de ser analisado, define o elemento, faz o upgrade de todo <glyph-fox> da página e substitui os placeholders.

Fixe a versão

glyphfox@1 acompanha a versão 1.x mais recente, o que é prático enquanto você prototipa. Em produção, fixe a versão exata e o arquivo, para que a página nunca mude sem você perceber e a CDN possa manter o arquivo em cache de forma permanente.

index.html
<script defer src="https://cdn.jsdelivr.net/npm/glyphfox@1.3.0/dist/web/glyphfox.min.js"></script>

Uma versão exata também permite usar Subresource Integrity: pegue o hash desse arquivo, que o jsDelivr lista para cada arquivo, e adicione integrity e crossorigin="anonymous" à tag. Um intervalo como @1 não comporta hash, porque o arquivo por trás dele muda a cada versão.

Você também pode hospedar o arquivo por conta própria. Copie node_modules/glyphfox/dist/web/glyphfox.min.js para a sua pasta pública e aponte a tag para ele: o arquivo é autossuficiente e não faz nenhuma outra requisição.

O elemento glyph-fox

Use o elemento para ícones que mudam: um nome que é trocado, um morph, um gatilho de hover ou clique, um estado. Ele lê todas as props dos próprios atributos e é redesenhado quando algum deles muda.

menu.html
<button type="button" class="menu" aria-label="Open menu" aria-expanded="false">
  <glyph-fox name="menu" morph duration="300"></glyph-fox>
</button>

<script type="module">
  const button = document.querySelector('.menu');
  const icon = button.querySelector('glyph-fox');
  button.addEventListener('click', () => {
    const open = button.getAttribute('aria-expanded') !== 'true';
    button.setAttribute('aria-expanded', String(open));
    button.setAttribute('aria-label', open ? 'Close menu' : 'Open menu');
    icon.setAttribute('name', open ? 'x' : 'menu');
  });
</script>

O atributo morph anima a troca de menu para x, um dos pares ajustados à mão. Estilização com shadow DOM, nomes de tag personalizados e gatilhos são explicados no guia de web components.

Placeholders com data-glyph

Para ícones que nunca mudam, um placeholder é mais leve que um elemento dinâmico. O runtime substitui todo elemento que tem o atributo data-glyph por SVG inline, copia a class dele para o svg e continua observando a página, então placeholders adicionados depois pelos seus scripts também são substituídos.

index.html
<i data-glyph="search" data-size="20"></i>
<i data-glyph="file+check@tr" data-weight="1.5"></i>
<i data-glyph="folder" data-variant="duotone" data-secondary-color="#ff7a1a"></i>
<i data-glyph="trash" class="danger" aria-label="Delete"></i>

As props são atributos data em kebab-case: data-size, data-weight, data-variant, data-modifier, data-animate e o restante da tabela abaixo. Um aria-label no placeholder vira o título do ícone, então o svg ganha um nome acessível.

A substituição acontece uma única vez. Depois dela, o placeholder deixa de existir, então mudar os atributos data dele não tem efeito, e os listeners ligados ao <i> se perdem junto. Ligue os listeners a um elemento pai, ou use o elemento quando o ícone precisar mudar.

Com um bundler, importe glyphfox/runtime em vez do arquivo da CDN. Ele exporta replaceGlyphs e o executa ao carregar, e inclui todos os ícones, já que uma página pode pedir qualquer nome. Não carregue esse módulo direto de uma CDN: ele importa o pacote como módulos ES separados, um arquivo por ícone, o que custa centenas de requisições. O build em arquivo único já contém o mesmo runtime.

A API global

O build da CDN também define window.glyphfox com a API do core: toSvg, fuse, search, getIcon, iconNames, categories, createMorph, toDataUri, replaceGlyphs e outras funções. Ela só existe depois que o script roda, então chame a API a partir de um script de módulo colocado depois da tag, ou após o DOMContentLoaded.

icon-search.html
<input type="search" id="q" placeholder="Search icons" aria-label="Search icons">
<div id="results"></div>

<script type="module">
  const { search, toSvg } = window.glyphfox;
  const q = document.getElementById('q');
  const results = document.getElementById('results');
  q.addEventListener('input', () => {
    results.innerHTML = search(q.value, { limit: 24 })
      .map((icon) => `<button type="button" aria-label="${icon.name}">${toSvg(icon.name, { size: 28 })}</button>`)
      .join('');
  });
</script>

toDataUri transforma uma string SVG em uma URL para backgrounds em CSS ou para um <img>. Uma imagem não consegue herdar o currentColor da página, então passe uma cor explícita.

checklist.js
const { toDataUri, toSvg } = window.glyphfox;
const check = toDataUri(toSvg('check', { size: 16, color: '#16a34a' }));
document.documentElement.style.setProperty('--icon-check', `url("${check}")`);
checklist.css
.done::before {
  content: '';
  display: inline-block;
  width: 16px;
  height: 16px;
  margin-right: 6px;
  background: var(--icon-check) no-repeat center / contain;
}

dist/web/glyphfox.esm.js é o mesmo build como módulo ES. O export padrão é o objeto da API e, assim como o arquivo clássico, ele define o elemento e executa o runtime de placeholders.

logo.html
<div id="logo"></div>

<script type="module">
  import glyphfox from 'https://cdn.jsdelivr.net/npm/glyphfox@1/dist/web/glyphfox.esm.js';

  document.getElementById('logo').innerHTML = glyphfox.toSvg('fox', { size: 48, variant: 'duotone' });
</script>

Tamanho do arquivo e quando fazer um build próprio

O arquivo único contém todos os ícones: 216,4 KB minificado, 62,4 KB com gzip. Servido por uma CDN com cache longo, é um preço justo para um protótipo, um site de documentação ou uma página que mostra muitos ícones diferentes. Para uma landing page que mostra seis, não compensa.

AbordagemO que é entregueIndicado para
Um script da CDNTodos os ícones, o elemento, o runtime e a API.Protótipos, documentação, páginas com muitos ícones.
Um bundler com glyphfox/web/elementO elemento e os ícones que você registra.Aplicações que já têm uma etapa de build, veja tree shaking.
Subconjunto em CSS pela CLIUma folha de estilo com uma classe de máscara por ícone e nenhum JavaScript.Sites estáticos e ícones que nunca mudam.
Subconjunto em sprite pela CLIUm arquivo SVG com um símbolo por ícone.HTML renderizado no servidor que repete os mesmos ícones, veja sprites SVG.
terminal
npx glyphfox build home search menu loader --type css --out public
npx glyphfox build home search menu loader --type sprite --out public/icons
index.html
<link rel="stylesheet" href="/glyphfox.css">

<span class="gf gf-home" aria-hidden="true"></span>
<span class="gf gf-loader gf-spin" aria-hidden="true"></span>

O build em CSS desenha cada ícone como uma máscara preenchida com currentColor, então ele assume a cor do texto e o tamanho da fonte, e inclui as animações gf-spin e gf-pulse. Todo comando aceita as props compartilhadas como flags, como --weight 1.5 ou --variant duotone.

Atributos

O elemento e os placeholders leem as mesmas props, sempre em kebab-case: como atributos simples em <glyph-fox>, por exemplo size e secondary-color, e com o prefixo data- nos placeholders, por exemplo data-size e data-secondary-color. O elemento também aceita layout, gap e morph.

AtributoTipoPadrãoDescrição
namestringnenhumA especificação do ícone: um nome, name+modifier@corner, a&b:layout ou name/variant.
layoutoverlap, side, stack, grid, orbit, badge, insidenenhumLayout da fusão quando o nome junta ícones com &.
gapnumber1Espaço de recorte de uma fusão, em unidades da grade.
morphbooleanfalseAnima toda troca de name como um morph.
sizenumber, string24Largura e altura; números são pixels.
colorstringcurrentColorCor principal.
secondary-colorstringcolorCor da camada duotone e do preenchimento sólido.
secondary-opacitynumber0.3 / 1Opacidade da camada duotone ou do preenchimento sólido.
weightnumber2Traço de 1 a 3 na grade de 24, com compensação óptica abaixo de 24 px.
absolute-weightbooleanfalseMantém o traço com weight pixels em qualquer tamanho.
cornersround, sharproundJunções e pontas redondas ou retas.
variantoutline, duotone, solidoutlineEixo de estilo; o sólido vem das formas fechadas.
rotatenumber0Rotação em graus.
flip-xbooleanfalseEspelha na horizontal.
flip-ybooleanfalseEspelha na vertical.
mirror-rtlbooleanfalseEspelha em layouts da direita para a esquerda.
animatedraw, pop, wiggle, spin, pulse, bounce, shakenenhumAnimação de estado vivo.
triggermount, hover, click, statemountQuando a animação ou o morph acontece.
activebooleanfalseO estado para o gatilho state.
durationnumber (ms)por animaçãoDuração da animação ou do morph.
delaynumber (ms)0Atraso da animação ou do morph.
loopboolean, numberfalseRepete para sempre ou um número de vezes (spin e pulse repetem por padrão).
modifierplus, minus, check, x, alert, lock, clock, sync, arrow-up, arrow-down, dotnenhumSelo com espaço de recorte automático.
modifier-cornertop-left, top-right, bottom-left, bottom-rightbottom-rightCanto do selo.
morph-toname, datanenhumDestino do morph; o gatilho decide quando aparece.
titlestringnenhumNome acessível: title, role img e aria-label.
decorativebooleantrue sem titleEsconde o ícone das tecnologias assistivas.

Armadilhas comuns

Scripts que rodam cedo demais
Um script clássico inline roda durante a análise do HTML, antes de um script da CDN com defer, então ali window.glyphfox ainda é undefined. Use type="module", já que scripts de módulo rodam depois dos scripts com defer, na ordem do documento, ou espere o DOMContentLoaded.
O módulo do runtime carregado de uma CDN
dist/runtime/auto.js foi feito para bundlers. Carregado direto no navegador, ele puxa o pacote um módulo por vez, um arquivo por ícone. Em páginas simples, use o build em arquivo único.
Placeholders são substituídos uma vez só
Mudar atributos data-* depois da substituição não tem efeito, e os listeners do placeholder são descartados. Use <glyph-fox> para ícones que mudam.
Elementos autofechados
Em HTML, <glyph-fox name="home" /> é uma tag aberta, então o conteúdo que vem depois some dentro do elemento. Sempre escreva a tag de fechamento.
currentColor em imagens
Um SVG carregado em um <img> ou usado como background CSS não enxerga a cor da página. Passe uma cor para toSvg, ou use o subconjunto em CSS, que funciona com máscaras.
Gatilhos de clique em placeholders
Placeholders viram SVG estático. Morphs e animações de hover continuam funcionando, porque são CSS dentro do SVG, mas os gatilhos de clique e de estado precisam do elemento, que alterna os estados para você.
Versões flutuantes em produção
glyphfox@1 muda a cada versão 1.x, e um arquivo alterado quebra o hash de integridade. Fixe glyphfox@1.0.0 e o caminho completo do arquivo.

Perguntas frequentes

Devo usar o elemento ou os placeholders data-glyph?

Placeholders para ícones que nunca mudam depois do carregamento: eles viram SVG inline simples, sem nenhum elemento dinâmico por trás. O elemento para ícones que trocam de nome, se transformam ou reagem a hover, clique ou estado. Os dois vêm do mesmo script e podem ser combinados na mesma página.

Funciona com HTML inserido depois, por exemplo pelo htmx?

Sim. O runtime observa o documento inteiro, então os placeholders dentro do HTML inserido são substituídos assim que chegam, e os elementos <glyph-fox> passam pelo upgrade ao serem inseridos, porque o elemento está definido para a página.

Ícones deste guia