Skip to content Skip to sidebar Skip to footer

How Can I Scale Arbitrary Text To Always Fit The Viewport Width?

A site I'm busy working on has a section with some very large headings. There's something I'm not sure how to handle: The heading may be one two short or long words, e.g: 'Cyprus'

Solution 1:

If you are looking to use a plugin there's

http://fittextjs.com/

wich can do that for you


Solution 2:

The only unit, if being used to set font size, that is relative to the size of its container, is viewport units vw/vh, which will not solve your case alone, even if the container is the same width as the viewport, since it does not calc the letter size to fit into the container.

The closest non-script solution I can come up with is to use the CSS element counter trick, and wrap each letter in a span

The 130vw I set here, worked best for the given font, though this might need to be adjusted based on which font family is being used.

h2 {
  display: inline-block;
  font-family: sans-serif;
  text-transform: uppercase;
  white-space: nowrap;
  overflow-x: hidden;
  margin: 0;
}

/* 1 letter */
h2 span:first-child:nth-last-child(1) {
    font-size: 130vw;
}
/* skipped 2-5 in this demo */

/* 6 letters */
h2 span:first-child:nth-last-child(6),
h2 span:first-child:nth-last-child(6) ~ span {
    font-size: calc(130vw / 6);
}

/* skipped 7-14 in this demo */

/* 15 letters */
h2 span:first-child:nth-last-child(15),
h2 span:first-child:nth-last-child(15) ~ span {
    font-size: calc(130vw / 15);
}
<h2><span>N</span><span>o</span><span>u</span><span>v</span><span>e</span><span>l</span><span>l</span><span>e</span> &nbsp;<span>Z</span><span>e</span><span>l</span><span>a</span><span>n</span><span>d</span><span>e</span></h2><br>
<h2><span>C</span><span>y</span><span>p</span><span>r</span><span>u</span><span>s</span></h2>

Here is the same concept using a script, and without the span's

(function (d,t) {
  window.addEventListener("resize", throttler, false);
  window.addEventListener("load", throttler(), false);  /*  run once on load to init  */
  
  function throttler() {
    if ( !t ) {
      t = setTimeout(function() {
        t = null;
        keepTextFit(d.querySelectorAll('h2'));
       }, 66);
    }
  }
  function keepTextFit(el) {
    var f = el[0].getAttribute("data-font");
    for (var i = 0; i < el.length; i++) {
      var c = el[i].textContent.split('').length;      
      el[i].style.cssText = 
        'font-size: calc(' + f + ' / ' + c + ')';
    }
  }
})(document,null);
h2 {
  display: inline-block;
  font-family: sans-serif;
  text-transform: uppercase;
  white-space: nowrap;
  overflow-x: hidden;
  margin: 0;
}
<h2 data-font="130vw">Nouvelle Zelande</h2>
<h2>Australia</h2>
<h2>Cyprus</h2>

Note, since resize events can fire at a high rate, the throttler is used to reduced the rate so the handler doesn't execute expensive operations such as DOM modifications too often.


If you want to make a perfect fit, check this post: fit-text-perfectly-inside-a-div


Post a Comment for "How Can I Scale Arbitrary Text To Always Fit The Viewport Width?"