Scoping SCSS @font-face variables for use with Font Face Observer

Issue

So I maintain a site where we use Font Face Observer: https://fontfaceobserver.com — we currently define fonts like this:

$serif: Georgia, Times, 'Times New Roman', serif;
$serifFontface: 'Chronicle Display', $serif;

%serif {
  font-family: $serif;
  .fonts-loaded&{
    font-family: $serifFontface;
  }
}

We are now in the process of modifying the codebase for use as a multilingual site, where there will always be both Roman and Japanese Kanji characters on a page.

We have a body class .isJa and I tried scoping like this, but the Kanji fontface appears in the stack even without the class being present on the body:

$serif: Georgia, Times, 'Times New Roman', serif;

.isJa{
  $serif: 'hiragino kaku gothic pro', Georgia, Times, 'Times New Roman', serif;
}

$serifFontface: 'Chronicle Display', $serif;

%serif {
  font-family: $serif;
  .fonts-loaded &{
    font-family: $serifFontface;
  }
}

How / is it possible to achieve the desired outcome? i.e. the hiragino font is only declared when .isJa is present, but is declared initially and also when Font Face Observer applies the .fonts-loaded class. I should probably add that we are limited to Sass v3.2.6

Solution

You got bitten by @extend. Extended rules are generated only once – in the exact moment when you declare the %placeholder. Changing variables later won’t affect them. This is (one of reasons) why using @extend in general is discouraged.

What you should do is to use a mixin that has a default parameter set to your initial variable value.

Code:

$serifFontface: 'Chronicle Display';

@mixin fontFallback($fallback: (Georgia, Times, 'Times New Roman', serif)) {
  font-family: $fallback;
  &.fonts-loaded {
    font-family: $serifFontface, $fallback;
  }
}

body {
  @include fontFallback;
}

.isJa {
  $japaneseFallback: 'hiragino kaku gothic pro', Georgia, Times, 'Times New Roman', serif;
  @include fontFallback($japaneseFallback);
}

Output:

body {
  font-family: Georgia, Times, "Times New Roman", serif;
}
body.fonts-loaded {
  font-family: "Chronicle Display", Georgia, Times, "Times New Roman", serif;
}

.isJa {
  font-family: "hiragino kaku gothic pro", Georgia, Times, "Times New Roman", serif;
}
.isJa.fonts-loaded {
  font-family: "Chronicle Display", "hiragino kaku gothic pro", Georgia, Times, "Times New Roman", serif;
}

Read more about mixins and extends here and here.

Answered By – JoannaFalkowska

Answer Checked By – David Goodson (AngularFixing Volunteer)

Leave a Reply

Your email address will not be published.