Font-Face CSS Auto-Generator

by AmberFG

HTML

<h1>Font-Face CSS Generator</h1>

  <label for="fontName">Font Name Label:
    <small style="display:block; font-weight: normal; font-size: 0.9rem;">
      (You can use any name — we’ll make it CSS-friendly automatically.)
    </small>
  </label>
  <input type="text" id="fontName" placeholder="e.g., My Cool Font!" required>
  <div id="fontNameError"></div>

  <label for="ttfUrl">.ttf File URL:</label>
  <input type="text" id="ttfUrl" placeholder="e.g., https://example.com/fonts/myfont.ttf">

  <label for="otfUrl">.otf File URL:</label>
  <input type="text" id="otfUrl" placeholder="e.g., https://example.com/fonts/myfont.otf">

  <label for="woffUrl">.woff File URL:</label>
  <input type="text" id="woffUrl" placeholder="e.g., https://example.com/fonts/myfont.woff">

  <label for="woff2Url">.woff2 File URL:</label>
  <input type="text" id="woff2Url" placeholder="e.g., https://example.com/fonts/myfont.woff2">

  <button onclick="generateCSS()">Generate CSS</button>

  <label for="outputCSS">Generated CSS:</label>
  <textarea id="outputCSS" readonly></textarea>

  <button onclick="copyToClipboard()">Copy to Clipboard</button>

CSS

body {
      font-family: sans-serif;
      padding: 2rem;
      max-width: 700px;
      margin: auto;
      background-color: #f9f9f9;
    }
    label {
      font-weight: bold;
    }
    input, textarea, button {
      width: 100%;
      padding: 0.5rem;
      margin: 0.5rem 0 1rem;
      font-size: 1rem;
    }
    textarea {
      height: 220px;
    }
    button {
      cursor: pointer;
    }
    #fontNameError {
      color: red;
      display: none;
      margin-top: -0.5rem;
      margin-bottom: 1rem;
    }

JavaScript

function generateCSS() {
      const fontNameRaw = document.getElementById('fontName').value.trim();
      const errorDiv = document.getElementById('fontNameError');

      if (!fontNameRaw) {
        errorDiv.textContent = "Please enter a font name.";
        errorDiv.style.display = 'block';
        return;
      }

      errorDiv.style.display = 'none';

      // Clean for CSS class name
      let cleanedName = fontNameRaw
        .toLowerCase()
        .replace(/[^a-z0-9_\- ]/gi, '') // Remove special chars
        .replace(/\s+/g, '-'); // Replace spaces with hyphens

      if (!/^[a-z_]/i.test(cleanedName)) {
        cleanedName = '_' + cleanedName;
      }

      const urls = {
        ttf: document.getElementById('ttfUrl').value.trim(),
        otf: document.getElementById('otfUrl').value.trim(),
        woff: document.getElementById('woffUrl').value.trim(),
        woff2: document.getElementById('woff2Url').value.trim(),
      };

      const sources = [];
      if (urls.ttf) sources.push(`    url('${urls.ttf}') format('truetype')`);
      if (urls.otf) sources.push(`    url('${urls.otf}') format('opentype')`);
      if (urls.woff) sources.push(`    url('${urls.woff}') format('woff')`);
      if (urls.woff2) sources.push(`    url('${urls.woff2}') format('woff2')`);

      if (sources.length === 0) {
        alert("Please provide at least one font file URL.");
        return;
      }

      const css = `@font-face {
  font-family: '${fontNameRaw}';
  src:
${sources.join(',\n')};
}

.${cleanedName}, 
.${cleanedName} p, 
.${cleanedName} h1, 
.${cleanedName} h2,
.${cleanedName} h3 {
  font-family: '${fontNameRaw}' !important;
  font-weight: normal;
  font-style: normal;
}`;

      document.getElementById('outputCSS').value = css;
    }

    function copyToClipboard() {
      const cssOutput = document.getElementById('outputCSS');
      cssOutput.select();
      cssOutput.setSelectionRange(0,...