Skip to content

Instantly share code, notes, and snippets.

@skoskie
Forked from jonathantneal/README.md
Last active September 25, 2024 17:35
Show Gist options
  • Save skoskie/b0d77b1a559124291a33cc88d3c8f64d to your computer and use it in GitHub Desktop.
Save skoskie/b0d77b1a559124291a33cc88d3c8f64d to your computer and use it in GitHub Desktop.
SASS @font-face mixin

Font Face Mixin

A mixin for writing @font-face rules in SASS. Embedded OpenType, WOFF2, WOFF, TrueType, and SVG files are automatically sourced.

Usage

Example One

Simplest scenario using default values:

$font_base_path: '/your/font/directory';

@include font-face(
    Samplino, 
    $font_base_path + '/Samplino - Book',
  );

Rendered as CSS:

@font-face {
  font-family: "Samplino";
  src: url("/your/font/directory/Samplino - Book.eot");
  src: url("/your/font/directory/Samplino - Book.eot?#iefix") format("eot"), url("/your/font/directory/Samplino - Book.woff2") format("woff2"), url("/your/font/directory/Samplino - Book.woff") format("woff"), url("/your/font/directory/Samplino - Book.ttf") format("truetype");
  font-style: normal;
  font-weight: normal;
  display: swap;
}

Example Two

More complex – create a @font-face rule that applies to bold and italic text, omits the eot format, and uses a fallback display strategy:

@include font-face(
    "Samplina Neue", 
    $font_base_path + '/Samplina Neue - Bold Oblique',
    bold,
    italic,
    fallback,
    woff2 woff ttf svg
  );

Rendered as CSS:

@font-face {
  font-family: "Samplina Neue";
  src: url("/your/font/directory/Samplina Neue - Bold Oblique.woff2") format("woff2"), url("/your/font/directory/Samplina Neue - Bold Oblique.woff") format("woff"), url("/your/font/directory/Samplina Neue - Bold Oblique.ttf") format("truetype"), url("/your/font/directory/Samplina Neue - Bold Oblique.svg#Samplina_Neue") format("svg");
  font-style: italic;
  font-weight: bold;
  display: fallback;
}

Example Three

You can pass null values to prevent properties from being renderd. Example – create a @font-face rule that only sources a WOFF and SVG file.

@include font-face(
    Samplinoff, 
    $font_base_path + '/Samplinoff', null, null, null, woff svg);

Rendered as CSS:

@font-face {
	font-family: "Samplinoff";
	src: url("/your/font/directory/Samplinoff.woff") format("woff"),
	     url("/your/font/directory/Samplinoff.svg") format("svg");
}

Notes

This snippet is forked from the original (props for getting it started) and has the following improvements:

  • Fixed support for legacy browsers all the way back to IE6. God help you if you actually need to support that browser.

  • Added the display property. Read more about it here.

Notes from the original snippet:

  • IE≥9 prioritizes valid font formats over invalid ones. Therefore, while embedded-opentype is the correct format for an .eot font, eot is used to fool modern IE into prioritizing other, newer font formats.

  • IE≤8 only supports .eot fonts and parses the src property incorrectly, interpreting everything between the first opening parenthesis ( and the last closing parenthesis ) as a single URL. Therefore, a ? is appended to the .eot’s URL, fooling older IE into reading all other sources as query parameters.

// =============================================================================
// Font Face
// =============================================================================
// Dependent Function: String Replace
@function str-replace($string, $search, $replace: "") {
$index: str-index($string, $search);
@if $index {
@return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
}
@return $string;
}
@mixin font-face(
$family_name,
$path,
$weight: null,
$style: null,
$display: swap,
$exts: eot woff2 woff ttf svg
) {
$src_eot: null;
$src_other: null;
$extmods: (
eot: "?#iefix",
svg: "#" + str-replace($family_name, " ", "_")
);
$formats: (
otf: "opentype",
ttf: "truetype"
);
// Setup the variables
@each $ext in $exts {
$extmod: if(map-has-key($extmods, $ext), $ext + map-get($extmods, $ext), $ext);
$format: if(map-has-key($formats, $ext), map-get($formats, $ext), $ext);
// "If a declaration’s value is null or an empty unquoted string,
// Sass won’t compile that declaration to CSS at all."
//
// That means if "eot" is not one of the requested font types, the following
// line will not appear in the compiled CSS file.
//
// @see https: //sass-lang.com/documentation/style-rules/declarations/#hidden-declarations
$src_eot: if($ext == "eot", append($src_eot, url(quote($path + "." + $ext))), $src_eot);
// All the other formats (including eot again).
$src_other: append($src_other, url(quote($path + "." + $extmod)) format(quote($format)), comma);
}
// Output
@font-face {
font-family: quote($family_name);
src: $src_eot;
src: $src_other;
font-style: $style;
font-weight: $weight;
display: $display;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment