How Icon Fonts Work

How does icon fonts work?

Icon fonts are fonts that contain symbols and glyphs instead of letters and numbers. They work much like regular fonts but display icons instead of text characters. Here's how they work and how they're used:


πŸ”§ How Icon Fonts Work

  1. Font File
    An icon font is a .ttf, .woff, or .eot file that contains vector shapes (icons) mapped to Unicode characters (just like how "A" maps to a specific shape in a text font).

  2. Character Mapping
    Each icon is assigned to a character code (e.g., \e900). When you type or reference that character in HTML/CSS, the font renders the corresponding icon.

  3. Usage in HTML
    You include the font file via CSS (@font-face) or through a service like Font Awesome. Then, you display an icon using HTML tags like <i> or <span> and a specific class.

  4. Styling with CSS
    Since icon fonts are text, you can style them with typical CSS properties: color, font-size, text-shadow, transform, etc.


🧱 Example

Assume you're using Font Awesome:

html
<!-- Include the icon font CSS --> <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet"> <!-- Use an icon --> <i class="fas fa-camera"></i>

This renders a camera icon. The class fas tells the browser to use the solid style of Font Awesome, and fa-camera refers to the camera icon mapped within the font.


βœ… Pros

  • Lightweight: One file can include hundreds of icons.

  • Scalable: Since icons are vector-based, they look sharp at any size.

  • Style with CSS: Easy to recolor, resize, or animate.


⚠️ Cons

  • Accessibility: They’re text-based but may not be readable by screen readers unless handled properly.

  • Complex Mapping: Mapping icons to characters can be confusing without documentation.

  • Outdated: Modern alternatives like SVG icons or icon components (React, Vue) are now more popular due to better accessibility and styling flexibility.


Would you like to see how to create a custom icon font from your own SVG icons?

How to create mine from a few svg files?

Creating your own icon font from a few SVG files is very doable and can be summarized in a few steps. Here’s a step-by-step guide using free tools, including some optional enhancements.


πŸ› οΈ Step-by-Step: Create Icon Font from SVGs


βœ… Step 1: Prepare Your SVG Icons

  • Make sure each icon is a clean, single-path SVG (preferably with a viewBox).

  • Name them clearly (e.g., home.svg, user.svg, settings.svg).


βœ… Step 2: Use an Icon Font Generator

πŸ”§ Recommended Tool: IcoMoon App

  1. Go to https://icomoon.io/app

  2. Click "Import Icons" and upload your SVG files.

  3. Select the icons you uploaded.

  4. Click "Generate Font" at the bottom.

  5. Click "Download" the generated font package.

You'll get a .zip file containing:

  • .woff, .ttf, .eot, .svg font files

  • style.css with class names

  • demo.html to preview and test your icons


βœ… Step 3: Use the Icon Font in Your Project

  1. Include the CSS in your HTML:

html
<link rel="stylesheet" href="fonts/style.css">
  1. Use icons like this:

html
<span class="icon-home"></span> <span class="icon-user"></span>

Class names are based on your original file names.


βœ… Step 4 (Optional): Customize Styling

Since they’re fonts, you can style with regular CSS:

css
.icon-home { font-size: 24px; color: #333; }

🎯 Optional Tools (Alternatives)


⚠️ Pro Tip: Accessibility

Use aria-hidden="true" and aria-label if icons convey meaning.

html
<span class="icon-user" aria-hidden="true"></span> <span class="sr-only">User Settings</span>

Would you like help creating an actual icon font set if you send me some SVG files?

How to do it programatically?

To create an icon font programmatically from SVG files, you can use Node.js tools that automate the process. The most popular tool is:


πŸ”§ Tool: webfont

This is a Node.js library that takes SVG files and generates font files (.woff, .ttf, .eot, etc.) along with optional CSS/HTML.


🧱 Step-by-Step (Code-Based Workflow)

βœ… 1. Install Dependencies

bash
npm init -y npm install webfont --save-dev

βœ… 2. Create a Script (e.g., generate-font.js)

js
const webfont = require('webfont').default; const fs = require('fs'); webfont({ files: 'icons/*.svg', // your SVG icons fontName: 'custom-icons', dest: 'dist/fonts', template: 'css', // can also be 'html', 'scss', etc. }).then((result) => { // Write font files for (const [filename, content] of Object.entries(result)) { if (filename !== 'config') { fs.writeFileSync(`dist/fonts/${filename}`, content); } } console.log('Icon font generated successfully!'); }).catch((err) => { console.error('Error:', err); });

βœ… 3. Create a Folder and Add SVGs

/icons - home.svg - user.svg - settings.svg

βœ… 4. Run the Script

bash
node generate-font.js

This will output:

/dist/fonts - custom-icons.woff - custom-icons.ttf - custom-icons.css - etc.

You can now use it in HTML:

html
<link rel="stylesheet" href="fonts/custom-icons.css"> <i class="icon-home"></i>

✨ Bonus: Customize Class Prefixes or Template

You can pass options like:

js
fontName: 'my-icons', templateClassName: 'icon', templateFontPath: './fonts/', cssFontsUrl: 'fonts/'

🧩 Alternative Programmatic Tools

  • fantasticon – CLI/Node.js tool with config support

  • svgicons2svgfont + svg2ttf – Lower-level control


Would you like a ready-to-run example project (zip or GitHub-style structure)?

I've heard that icon fonts run into problems with stroke-only icons

Yes, you heard right β€” icon fonts struggle with stroke-only SVG icons, and this is a well-known limitation. Here's a clear explanation of why this happens and what to do about it:


⚠️ Why Stroke-Only SVGs Are a Problem for Icon Fonts

🧩 Fonts Are Filled Shapes Only

Icon fonts (like all fonts) render only filled vector paths. They do not preserve stroke properties like:

  • stroke-width

  • stroke-linecap

  • stroke-linejoin

  • stroke color

πŸ” What Happens:

If your SVG icon is composed only of strokes (lines), once converted into a font glyph:

  • The strokes disappear

  • Or get converted into very thin filled paths, often invisible

πŸ“‰ Result: Broken or Invisible Icons


βœ… How to Fix It

βœ… 1. Convert Strokes to Outlined Paths

You need to convert strokes to filled paths (also called "expand stroke" or "outline stroke").

πŸ”§ Using Inkscape:

  • Open the SVG

  • Select the stroke

  • Go to Path > Stroke to Path

  • Save/export the modified SVG

πŸ”§ Using Adobe Illustrator:

  • Select stroke paths

  • Choose Object > Path > Outline Stroke

This turns strokes into filled shapes, which will work in font glyphs.


βœ… 2. Prefer Filled SVGs for Fonts

When designing icons for use as fonts:

  • Use filled shapes or combine strokes with fills

  • Flatten/expand strokes before generating fonts


πŸ’‘ Alternative: Use SVG Icons Directly (Not Fonts)

Modern setups often favor SVG icons over icon fonts because:

  • SVG preserves strokes and styles

  • Better accessibility and styling control

  • You can inline SVG or use it via <img> or as a background


Summary

Feature Icon Font Inline SVG
Preserves strokes ❌ βœ…
Fully styleable in CSS βœ… (limited) βœ…
Accessibility-friendly ⚠️ βœ…
Easy scaling βœ… βœ…

Would you like a script or tool suggestion to batch-convert all your stroke-based SVGs to filled shapes?

yes

Great! Here's how you can batch-convert stroke-only SVG icons into filled paths using Inkscape CLI β€” a reliable and scriptable tool that works on macOS, Linux, and Windows.


βœ… Option 1: Batch Convert Strokes to Paths with Inkscape (CLI)

πŸ› οΈ Step-by-Step

1. Install Inkscape

  • macOS (Homebrew):

    bash
    brew install --cask inkscape
  • Ubuntu/Linux:

    bash
    sudo apt install inkscape
  • Windows:
    Download from: https://inkscape.org/release/


2. Run Batch Script (Bash)

Here’s a simple shell script that:

  • Takes all .svg files in a folder

  • Converts strokes to paths

  • Saves them in a new folder (out/)

bash
#!/bin/bash mkdir -p out for file in *.svg; do inkscape "$file" \ --actions="select-all;object-to-path;stroke-to-path;export-filename:out/$file;export-do" \ --export-type=svg done echo "Conversion complete. Output in ./out/"

Save as convert-strokes.sh, then:

bash
chmod +x convert-strokes.sh ./convert-strokes.sh

🧠 What This Does:

  • select-all – selects all elements

  • object-to-path – converts shapes to path

  • stroke-to-path – turns strokes into filled outlines

  • export-filename and export-do – saves to output folder


βœ… Option 2: Node.js Alternative with Puppeteer (for full automation)

If you need a cross-platform Node-based script, I can provide one using Puppeteer and Inkscape in headless mode β€” let me know.


βœ… Option 3: GUI Batch via Inkscape Extensions

In the GUI:

  • Use Inkscape > Extensions > Modify Path > Stroke to Path

  • Apply to all, save, repeat for each β€” slower but good for testing


Would you like me to package the shell script into a complete working folder for you?

Give me option 2

Awesome β€” here’s Option 2, a fully scriptable Node.js solution to batch convert stroke-only SVGs into filled-paths using Puppeteer (a headless Chromium browser) and Inkscape’s GUI logic simulated.

Since Inkscape CLI doesn't always support detailed stroke manipulation across OSes, this method mimics user actions in a headless browser.


πŸš€ Node.js + Puppeteer-Based SVG Stroke-to-Path Converter

βœ… Step 1: Set Up Project

bash
mkdir svg-stroke-converter cd svg-stroke-converter npm init -y npm install puppeteer

βœ… Step 2: Add Script convert-svg-strokes.js

js
const fs = require('fs'); const path = require('path'); const puppeteer = require('puppeteer'); const inputDir = path.resolve(__dirname, 'input'); const outputDir = path.resolve(__dirname, 'output'); if (!fs.existsSync(outputDir)) fs.mkdirSync(outputDir); (async () => { const browser = await puppeteer.launch({ headless: true }); const page = await browser.newPage(); const files = fs.readdirSync(inputDir).filter(f => f.endsWith('.svg')); for (const file of files) { const inputPath = path.join(inputDir, file); const outputPath = path.join(outputDir, file); const svg = fs.readFileSync(inputPath, 'utf8'); await page.setContent(svg); await page.evaluate(() => { const svg = document.querySelector('svg'); const ns = "http://www.w3.org/2000/svg"; function strokeToPath(el) { const bbox = el.getBBox(); const clone = el.cloneNode(true); // Convert stroke to outline approximation (basic fallback) clone.setAttribute('fill', el.getAttribute('stroke') || '#000'); clone.removeAttribute('stroke'); clone.removeAttribute('stroke-width'); svg.replaceChild(clone, el); } const paths = svg.querySelectorAll('[stroke]'); paths.forEach(el => strokeToPath(el)); }); const finalSvg = await page.content(); const cleanSvg = finalSvg .replace(/<!DOCTYPE[^>]*>/, '') .replace(/<html.*?>.*?<body.*?>/, '') .replace(/<\/body><\/html>/, '') .trim(); fs.writeFileSync(outputPath, cleanSvg); console.log(`Converted: ${file}`); } await browser.close(); })();

βœ… Step 3: Folder Structure

svg-stroke-converter/ β”œβ”€β”€ input/ β”‚ └── your-stroke-icons.svg β”œβ”€β”€ output/ ← generated icons β”œβ”€β”€ convert-svg-strokes.js

Put your SVG icons in the input/ folder.


βœ… Step 4: Run the Script

bash
node convert-svg-strokes.js

Output will be saved in the output/ folder, with strokes replaced by filled shapes.


⚠️ Notes

  • This uses a visual approximation method β€” not 100% precise like Illustrator or Inkscape's Stroke to Path, but works well for simple icons.

  • If you want pixel-perfect conversion, I still recommend batch automating Inkscape or Illustrator with CLI access.


Would you like a downloadable .zip project with this setup ready to run?

Isn't there a node.js package for this conversion?

Yes β€” there is a Node.js package for converting strokes to paths in SVGs more reliably and natively: πŸ› οΈ svg-path-stroker, plus a few supporting libraries.

However, there is no single Node.js package that fully replicates Inkscape's stroke-to-path precision (e.g., variable stroke caps, joins, dash arrays). That said, here are the best realistic options:


βœ… Option 1: svg-path-stroker

πŸ’‘ What it does:

  • Converts an SVG path element with a stroke into two filled paths approximating the stroke.

  • Designed for icon/font generation (used in Fontello).

🚫 Limitations:

  • Only works with <path> elements (not <circle>, <line>, <rect>, etc.)

  • No support for advanced stroke styles (e.g., round caps, dashes)


πŸ”§ Install & Use

bash
npm install svg-path-stroker svgpath
js
const stroker = require('svg-path-stroker'); const SvgPath = require('svgpath'); // Example stroke path const originalPath = new SvgPath('M10 10 H 90 V 90 H 10 Z'); const strokeWidth = 10; const outlined = stroker(originalPath.abs().toString(), strokeWidth, { join: 'miter', cap: 'butt', }); // `outlined` is a filled path string console.log('Outlined Path:', outlined);

βœ… Option 2: Use svg2ttf or svgicons2svgfont

These libraries are used internally in icon font generators to flatten strokes into glyph-compatible filled paths, but they:

  • Expect already-clean path data

  • Work best after strokes are converted manually


βœ… Option 3: Automate Inkscape (Best Quality)

As mentioned before, Inkscape’s CLI (stroke-to-path) is still the most accurate method. You can call it from Node.js:

πŸ“¦ Using child_process:

js
const { execSync } = require('child_process'); const input = 'icons/home.svg'; const output = 'converted/home.svg'; execSync(`inkscape "${input}" --actions="select-all;stroke-to-path;export-filename:${output};export-do"`);

This gives you 100% accurate results with all SVG shapes and stroke styles.


πŸ”š Summary

Package/Method Stroke-to-Path Quality Shapes Supported Ideal For
svg-path-stroker Basic Paths only Icon fonts
Inkscape CLI βœ… Best (full SVG spec) All Precision icons
Puppeteer/DOM tricks Medium (approximation) Most Lightweight fallback
svgicons2svgfont Indirect After stroke fix Font pipeline only

Would you like a full working Node.js project that wraps the svg-path-stroker logic for batch conversion?