seek-oss / capsize

Flipping how we define typography in CSS.

Home Page:https://seek-oss.github.io/capsize/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Expose SCSS mixin?

AndrewLeedham opened this issue · comments

Capsize is great! I am working on adding it to a project. Given the stack I am using the only way of dynamically generating the CSS is via a SASS mixin. I therefore had to mimick the JS calculations, so I was curious if it would be something you would considering exposing from within capsize itself? If so, I can put a PR in for it 👍

Hey 👋

Only hesitance i would have to include it in capsize is having to keep multiple implementations of the calculations in sync, with the danger being divergence over time. This get compounded by other consumers needing different preprocessor support. Im just trying to think it through first.

Without being across the ecosystem, is there anyway to run javascript within a sass pipeline somehow?

Yeah I can see the maintenance burden.

My original angle was trying to integrate the JS version into SASS somehow, but the only API exposed is for functions: https://sass-lang.com/documentation/js-api#functions which lets you programatically create values not entire rules :(

Perhaps this would make sense as a separate package, maintained separately? capsize-sass perhaps?

Maybe yeah. Can i ask what the sass version of capsize looks like? Do you have a link you can share?

Sure here is the code:

// capsize.scss
@use "sass:map";
@use "sass:math";

$-font-metrics: (
  capHeight: 1456,
  ascent: 1900,
  descent: -500,
  lineGap: 0,
  unitsPerEm: 2048,
);
$-precision: 4;
$-prevent-collapse: 0.05;

@function to-scale($value, $font-size) {
  @return $value / $font-size;
}

@function leading-trim($value, $specified-line-height-offset, $font-size) {
  @return $value - to-scale($specified-line-height-offset, $font-size) +
    to-scale($-prevent-collapse, $font-size);
}

@function round-to($float, $decimal) {
  $pow: math.pow(10, $decimal);
  @return round($float * $pow) / $pow;
}

@function strip-unit($number) {
  @if type-of($number) == "number" and not unitless($number) {
    @return $number / ($number * 0 + 1);
  }

  @return $number;
}

@mixin capsize($font-size, $line-height) {
  $font-size: strip-unit($font-size);
  $line-height: strip-unit($line-height);
  $absolute-descent: math.abs(map.get($-font-metrics, "descent"));
  $cap-height-scale: map.get($-font-metrics, "capHeight") /
    map.get($-font-metrics, "unitsPerEm");
  $descent-scale: $absolute-descent / map.get($-font-metrics, "unitsPerEm");
  $ascent-scale: map.get($-font-metrics, "ascent") /
    map.get($-font-metrics, "unitsPerEm");
  $line-gap-scale: map.get($-font-metrics, "lineGap") /
    map.get($-font-metrics, "unitsPerEm");

  $content-area: map.get($-font-metrics, "ascent") +
    map.get($-font-metrics, "lineGap") + $absolute-descent;
  $line-height-scale: $content-area / map.get($-font-metrics, "unitsPerEm");
  $line-height-normal: $line-height-scale * $font-size;

  $specified-line-height-offset: if(
    $line-height,
    ($line-height-normal - $line-height) / 2,
    0
  );

  font-size: #{round-to($font-size, $-precision)}px;
  line-height: if(
    $line-height,
    #{round-to($line-height, $-precision)}px,
    "normal"
  );
  padding: #{$-prevent-collapse}px 0;
  &::before {
    content: "";
    margin-top: #{round-to(
        leading-trim(
            $ascent-scale - $cap-height-scale + $line-gap-scale / 2,
            $specified-line-height-offset,
            $font-size
          ) * -1,
        $-precision
      )}em;
    display: block;
    height: 0;
  }
  &::after {
    content: "";
    margin-top: #{round-to(
        leading-trim(
            $descent-scale + $line-gap-scale / 2,
            $specified-line-height-offset,
            $font-size
          ) * -1,
        $-precision
      )}em;
    display: block;
    height: 0;
  }
}

Usage looks like this:

@use "path/to/capsize" as *;
.h1 {
  @include capsize(48px, 52px);
}

Update: note that this will only work with dart-sass not node-sass since node-sass is behind on some of the new SASS features.

Yeah it definitely would take a bit of work keeping these in sync. Might be best to go with the separate repo and get some traction that way at this stage. Can always revisit this down the track if we feel there is a sustainable way to bring the two together.

Sounds like a plan. Are you happy if I publish capsize-sass under our org with credit and links back to capsize of course :) ?

Sounds sensible to me 👌

An update on this, we ended moving away from sass, and https://www.npmjs.com/package/capsize-sass was release before I got a chance to release my version. If anyone wants to use the mixin included above, feel free.