Two-way enlarger (w/function)

This experiment solves the arbitrary "hunting and pecking" issue, using Sass functions and simple math to figure out what combination of settings would give us the font size we desire at the breakpoint where we want the switch between increasing upward and increasing downward to occur.

Let's say we want the base font size to be 12px, and that we want the text to be that size at the 800px breakpoint.  On this particular site, 800px is represented by the $md breakpoint (I use Snugug's breakpoint-sass; it's easy and reliable).  In this example, we also have decided that we want the font size to increase at a rate of 1.75vw on the way up past 800px, and at a rate of 1.0vw on the way down.

Our Sass, therefore, is as follows:

$threshold-px: 12px;
$switch-point: $md;
$vw-rate-up: 1.75vw;
$vw-rate-down: 1.0vw;

$up-size: baseFontSize($threshold-px, $switch-point, $vw-rate-up, 'add');
$down-size: baseFontSize($threshold-px, $switch-point, $vw-rate-down, 'subtract');

html {
  font-size: calc( #{$down-size} - #{$vw-rate-down} );
  @include breakpoint($switch-point) {
    font-size: calc( #{$up-size} + #{$vw-rate-up} );
  }
}

Here, then, is our Sass function.  Sass functions are written in simple .scss files, and they can be placed anywhere -- I stick them in their own functions directory, and I call them pretty early in my Sass chain, right after I declare my variables. 

The function receives the four values we're sending it, and the first thing it does is strip the units from the numerical arguments, using a function I found at css-tricks.com called strip-unit.

Next, it makes a fairly simple calculation -- It multiplies the breakpoint by the viewport factor, or 800 x 1.75, then divides that value by 100 to give us 14, which is 1.75vw's value in pixels when the viewport is 800px wide.

Finally, we either add or subtract this value from the desired value in pixels (depending on whether we are going up or down), and that magically gives us the value that we then add or subtract our vw value back in our original Sass.

@function baseFontSize($thresholdPx, $switchPoint, $vwRate, $operation) {

  $fontsize: strip-unit($thresholdPx);
  $breakpoint: strip-unit($switchPoint);
  $viewportFactor: strip-unit($vwRate);

  $fontsize-at-breakpoint: ($breakpoint * $viewportFactor) / 100;

  @if $operation == 'add' {
    $number: $fontsize - $fontsize-at-breakpoint;
    @return #{$number}px;
  }
  @else {
    $number: $fontsize + $fontsize-at-breakpoint;
    @return #{$number}px;
  }
}