Skip to content

Instantly share code, notes, and snippets.

@mturnwall
Last active March 6, 2019 22:35
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mturnwall/2f54cbe507422042fdaa to your computer and use it in GitHub Desktop.
Save mturnwall/2f54cbe507422042fdaa to your computer and use it in GitHub Desktop.
Sass Font-Face Generator Mixins
// ----
// libsass (v3.2.5)
// ----
////
/// Font-Face Generator (FF)
/// @author Hugo Giraudel, Michael Turnwall
////
/// Path to the location of the font files
/// @type String
$ff-dir: '/fonts' !default;
/// List storing all the fonts to import.
/// The `name` key is the name of the file minus the file extension.
/// The keys for `formats`, `weight` and `style` are optional. If you
/// leave off formats you'll get `woff` and `ttf` formats by default.
/// Both `weight` and `style` default to normal.
/// @type List
/// @example scss
/// // Here is how the map should be setup.
/// $ff-map: (
/// "Proxima-Nova": ( // font-family name
/// (
/// "name": "Proxima-Nova-Light",
/// "formats": ("woff", "ttf"),
/// "weight": 300
/// ), (
/// "name": "Proxima-Nova-LightItalic",
/// "weight": 300,
/// "style": "italic"
/// ), (
/// "name": "Proxima-Nova-Regular"
/// ), (
/// "name": "Proxima-Nova-Medium",
/// "weight": 500
/// ), (
/// "name": "Proxima-Nova-Bold",
/// "weight": 700
/// )
/// )
/// );
/// @group fonts
$ff-map: () !default;
/// Function to build a valid `src` from a map of sources
/// @param {Map} $font - Font to build the source for
/// @return {List}
/// @group fonts
/// @access private
@function ff-build-src($font) {
$src: ();
$name: map-get($font, name);
@each $format in map-get($font, formats) {
$src: append($src, url($ff-dir + "/" + $name + "." + unquote($format)) format(quote($format)), "comma");
}
@return $src;
}
/// Import a single font.
/// @param {String} $name - Name of the font to import
/// @param {List} $src - Sources of the font to import
/// @param {String | Number} $weight [normal] - Weight of the font to import
/// @param {String | Number} $style [normal] - Style of the font to import
/// @group fonts
@mixin ff-single($fontName, $src, $weight: normal, $style: normal) {
@at-root {
@font-face {
font-family: quote($fontName);
src: $src;
font-weight: unquote($weight);
font-style: unquote($style);
}
}
}
/// This mixin is used to create a batch of @font-face rules using
/// a Sass map.
/// @param {Map} $fonts - a Sass map of the fonts
///
/// @see $ff-map
/// @requires ff-single
/// @requires ff-get-src
/// @group fonts
@mixin ff-batch($fonts) {
@each $font-group-name, $font-groups in $fonts {
@each $font in $font-groups {
// default to woff and ttf if formats is missing
@if map-get($font, formats) {
$src: ff-build-src($font);
} @else {
$src: ff-build-src(map-merge($font, ("formats": ("woff", "ttf"))));
}
$font: map-merge(map-remove($font, name, formats), ("src": $src));
@include ff-single($font-group-name, $font...);
}
}
}
//***** Usage *****\\
// Create a batch of @font-face rules
// 1. setup your map
$ff-map: (
"Proxima-Nova": (
(
"name": "Proxima-Nova-Light",
"formats": ("woff", "ttf"),
"weight": 300
), (
"name": "Proxima-Nova-LightItalic",
weight: 300,
style: "italic"
), (
"name": "Proxima-Nova-Regular"
), (
"name": "Proxima-Nova-Medium",
weight: 500
), (
"name": "Proxima-Nova-Bold",
weight: 700
)
)
);
// 2. pass your map to the mixin
@include ff-batch($ff-map);
// Single use, just make sure the $src argument is a Sass list.
// Using a variable is easier.
$icomoon-list:
url("/fonts/icomoon.woff") format("woff"),
url("/fonts/icomoon.ttf") format("ttf"),
url("/fonts/icomoon.svg") format("svg");
@include ff-single('icomoon', $icomoon-list);
@font-face {
font-family: "Proxima-Nova";
src: url("/fonts/Proxima-Nova-Light.woff") format("woff"), url("/fonts/Proxima-Nova-Light.ttf") format("ttf");
font-weight: 300;
font-style: normal;
}
@font-face {
font-family: "Proxima-Nova";
src: url("/fonts/Proxima-Nova-LightItalic.woff") format("woff"), url("/fonts/Proxima-Nova-LightItalic.ttf") format("ttf");
font-weight: 300;
font-style: italic;
}
@font-face {
font-family: "Proxima-Nova";
src: url("/fonts/Proxima-Nova-Regular.woff") format("woff"), url("/fonts/Proxima-Nova-Regular.ttf") format("ttf");
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: "Proxima-Nova";
src: url("/fonts/Proxima-Nova-Medium.woff") format("woff"), url("/fonts/Proxima-Nova-Medium.ttf") format("ttf");
font-weight: 500;
font-style: normal;
}
@font-face {
font-family: "Proxima-Nova";
src: url("/fonts/Proxima-Nova-Bold.woff") format("woff"), url("/fonts/Proxima-Nova-Bold.ttf") format("ttf");
font-weight: 700;
font-style: normal;
}
@font-face {
font-family: "icomoon";
src: url("/fonts/icomoon.woff") format("woff"), url("/fonts/icomoon.ttf") format("ttf"), url("/fonts/icomoon.svg") format("svg");
font-weight: normal;
font-style: normal;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment