Dynamic Font Size

by Marc Malignan

HTML

<div id="container">
  <div id="big" class="text-dynamic">Sézane</div>
  <div id="medium" class="text-dynamic">Sézane & Octobre</div>
  <div id="small" class="text-dynamic">Trop cool, j'ai trop hâte de voir ça !</div>
</div>

CSS

* {
  box-sizing: border-box;
}

body {
  margin: 0;
}

#container {
  margin: 0 auto;
  width: 100%;
  max-width: 800px;
  background: silver;
}

.text-dynamic {
  display: flex;
  justify-content: space-between;
  white-space: nowrap;
  overflow: hidden;
}

JavaScript

const debounce = func => {
  let timer;
  return event => {
    if (timer) clearTimeout(timer);
    timer = setTimeout(func, 100, event);
  };
}

// split text into spans
const splitDynamicText = (id) => {
  const el = document.getElementById(id);
  const text = el.textContent.trim();
  let content = '';
  text.split('').forEach(char => {
    if (char === ' ') {
      content += `<span>&nbsp;</span>`;
    } else {
      content += `<span>${char}</span>`;
    }
  });
  el.innerHTML = content;
}

// set font size depending on text length and element width
const computeDynamicText = (id, ratio) => {
  const el = document.getElementById(id);
  const text = el.textContent.trim();
  const width = el.offsetWidth;
  const fontSize = Math.pow(text.length, -1) * width * ratio;
  el.style.fontSize = `${fontSize}px`;
}

const resize = (id, ratio) => {
  splitDynamicText(id);
  computeDynamicText(id, ratio);
  window.addEventListener('resize', debounce(() => computeDynamicText(id, ratio)));
}

resize('big', 2);
resize('medium', 2);
resize('small', 2);