Create a gist now

Instantly share code, notes, and snippets.

Embed
SASS @font-face mixin

Font Face

A mixin for writing @font-face rules in SASS.

Usage

Create a font face rule. Embedded OpenType, WOFF2, WOFF, TrueType, and SVG files are automatically sourced.

@include font-face(Samplino, fonts/Samplino);

Rendered as CSS:

@font-face {
	font-family: "Samplino";
	src: url("fonts/Samplino.eot?") format("eot"),
		 url("fonts/Samplino.woff2") format("woff2"),
		 url("fonts/Samplino.woff") format("woff"),
		 url("fonts/Samplino.ttf") format("truetype"),
		 url("fonts/Samplino.svg#Samplino") format("svg");
}

Create a font face rule that applies to bold and italic text.

@include font-face("Samplina Neue", fonts/SamplinaNeue, bold, italic);

Rendered as CSS:

@font-face {
	font-family: "Samplina Neue";
	font-style: italic;
	font-weight: bold;
	src: url("fonts/SamplinaNeue.eot?") format("eot"),
	     url("fonts/SamplinaNeue.woff2") format("woff2"),
	     url("fonts/SamplinaNeue.woff") format("woff"),
	     url("fonts/SamplinaNeue.ttf") format("truetype"),
	     url("fonts/SamplinaNeue.svg#Samplina_Neue") format("svg");
}

Create a font face rule that only sources a WOFF.

@include font-face(Samplinoff, fonts/Samplinoff, null, null, woff);

Rendered as CSS:

@font-face {
	font-family: "Samplinoff";
	src: url("fonts/Samplinoff.woff") format("woff");
}

Create a font face rule that applies to 500 weight text and sources EOT, WOFF2, and WOFF.

@include font-face(Samplinal, fonts/Samplinal, 500, normal, eot woff2 woff);

Rendered as CSS:

@font-face {
	font-family: "Samplinal";
	font-style: normal;
	font-weight: 500;
	src: url("fonts/Samplinal.eot?") format("eot"),
	     url("fonts/Samplinal.woff2") format("woff2"),
	     url("fonts/Samplinal.woff") format("woff");
}

Notes

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.

// =============================================================================
// 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;
}
// =============================================================================
// Font Face
// =============================================================================
@mixin font-face($name, $path, $weight: null, $style: null, $exts: eot woff2 woff ttf svg) {
$src: null;
$extmods: (
eot: "?",
svg: "#" + str-replace($name, " ", "_")
);
$formats: (
otf: "opentype",
ttf: "truetype"
);
@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);
$src: append($src, url(quote($path + "." + $extmod)) format(quote($format)), comma);
}
@font-face {
font-family: quote($name);
font-style: $style;
font-weight: $weight;
src: $src;
}
}
@WhiteBeetle

This comment has been minimized.

Show comment
Hide comment
@WhiteBeetle

WhiteBeetle Jan 3, 2015

Hey, Djb... Love the heart. Gotta admit I'm catching up fast with my limited and geofenced redirected bogus app store apps and all the rest. Not bad eh? MKA- Mobility Kit for Android? Wag? Windows Android Grant? We are Global? What about Grant?

Hey, Djb... Love the heart. Gotta admit I'm catching up fast with my limited and geofenced redirected bogus app store apps and all the rest. Not bad eh? MKA- Mobility Kit for Android? Wag? Windows Android Grant? We are Global? What about Grant?

@Leaderproxima

This comment has been minimized.

Show comment
Hide comment
@Leaderproxima

Leaderproxima Oct 16, 2015

Hi,

I'm trying to use this mixin on my stylesheet but i've encountered an issue. When choosing a font that is in a higher directory (eg. one folder up) then it encounters an issue at compile.

What I want it to display:

@font-face {
  font-family: "SoftElegance";
  src: url("../fonts/SoftElegance.ttf") format("truetype"); }

The "../" breaks the mixin and doesn't allow it to compile. Anyway to include the ability to use parent directories instead of having to have the fonts folder inside my css folder?

Hi,

I'm trying to use this mixin on my stylesheet but i've encountered an issue. When choosing a font that is in a higher directory (eg. one folder up) then it encounters an issue at compile.

What I want it to display:

@font-face {
  font-family: "SoftElegance";
  src: url("../fonts/SoftElegance.ttf") format("truetype"); }

The "../" breaks the mixin and doesn't allow it to compile. Anyway to include the ability to use parent directories instead of having to have the fonts folder inside my css folder?

@inseldesign

This comment has been minimized.

Show comment
Hide comment
@inseldesign

inseldesign Dec 13, 2015

It works for me with @include font-face(Samplino, "../fonts/Samplino");

It works for me with @include font-face(Samplino, "../fonts/Samplino");

@DerExilant

This comment has been minimized.

Show comment
Hide comment
@DerExilant

DerExilant Jan 25, 2016

I do also have a problem with the code. It says:
Invalid CSS after "... $replace: "") ": expected expression (e.g. 1px, bold), was "{")

I do also have a problem with the code. It says:
Invalid CSS after "... $replace: "") ": expected expression (e.g. 1px, bold), was "{")

@anup04sust

This comment has been minimized.

Show comment
Hide comment
@anup04sust

anup04sust Feb 12, 2016

I do also have a problem with the code. It says
Syntax error: Invalid CSS after " eot": expected ")", was ": "?","
on line 23 of []/scss/mixin/_fontface.scss

I do also have a problem with the code. It says
Syntax error: Invalid CSS after " eot": expected ")", was ": "?","
on line 23 of []/scss/mixin/_fontface.scss

@mamsoudi

This comment has been minimized.

Show comment
Hide comment
@mamsoudi

mamsoudi Mar 18, 2016

Thank you for the mixin! Works perfectly!

Thank you for the mixin! Works perfectly!

@fabiowitt

This comment has been minimized.

Show comment
Hide comment

Nice job!

@sjdeere

This comment has been minimized.

Show comment
Hide comment
@sjdeere

sjdeere Apr 12, 2016

what if there is no woff2
@include font-face("name", "https://cdn.domain/fonts/fontname_LT_4_, 400", normal, eot woff ttf svg);

i look at the output and woff2 is also output

sjdeere commented Apr 12, 2016

what if there is no woff2
@include font-face("name", "https://cdn.domain/fonts/fontname_LT_4_, 400", normal, eot woff ttf svg);

i look at the output and woff2 is also output

@obcidio

This comment has been minimized.

Show comment
Hide comment
@obcidio

obcidio Apr 12, 2016

Beautiful.

For anyone else's info, place your paths in quotes and as another variable. Also, remember the path is relative to the final destination of the output css file(s).

obcidio commented Apr 12, 2016

Beautiful.

For anyone else's info, place your paths in quotes and as another variable. Also, remember the path is relative to the final destination of the output css file(s).

@vishalPGit

This comment has been minimized.

Show comment
Hide comment
@vishalPGit

vishalPGit Jun 9, 2016

Use @include font-face(Samplino, "../fonts/Samplino") instead of @include font-face(Samplino, ../fonts/Samplino) and its working for me.
Thanks

Use @include font-face(Samplino, "../fonts/Samplino") instead of @include font-face(Samplino, ../fonts/Samplino) and its working for me.
Thanks

@surayashivji

This comment has been minimized.

Show comment
Hide comment
@surayashivji

surayashivji Sep 4, 2016

If we create this as an @function instead of an @mixin to create font variables, is it syntactically correct to say

@return @font-face {
font-family : quote($name); // add quotes to name string
font-style: $style;
font-weight: $weight;
src: $src;
}

also, does the mixin's name, font-face have anything to do with setting the font-face's values at the end of the mixin?

If we create this as an @function instead of an @mixin to create font variables, is it syntactically correct to say

@return @font-face {
font-family : quote($name); // add quotes to name string
font-style: $style;
font-weight: $weight;
src: $src;
}

also, does the mixin's name, font-face have anything to do with setting the font-face's values at the end of the mixin?

@vovan4

This comment has been minimized.

Show comment
Hide comment
@vovan4

vovan4 Oct 3, 2016

=font-face($font-family, $file-path, $font-weight: normal, $font-style: normal)
@font-face
font-family: $font-family
src: url('#{$file-path}.eot')
src: url('#{$file-path}.eot?#iefix') format('embedded-opentype'), url('#{$file-path}.woff2') format('woff2'), url('#{$file-path}.woff') format('woff'), url('#{$file-path}.ttf') format('truetype'), url('#{$file-path}.svg##{$font-family}') format('svg')
font-weight: $font-weight
font-style: $font-style

// Chrome for Windows rendering fix: http://www.adtrak.co.uk/blog/font-face-chrome-rendering/
@media screen and (-webkit-min-device-pixel-ratio: 0)
@font-face
font-family: $font-family
src: url('#{$file-path}.svg##{$font-family}') format('svg')

vovan4 commented Oct 3, 2016

=font-face($font-family, $file-path, $font-weight: normal, $font-style: normal)
@font-face
font-family: $font-family
src: url('#{$file-path}.eot')
src: url('#{$file-path}.eot?#iefix') format('embedded-opentype'), url('#{$file-path}.woff2') format('woff2'), url('#{$file-path}.woff') format('woff'), url('#{$file-path}.ttf') format('truetype'), url('#{$file-path}.svg##{$font-family}') format('svg')
font-weight: $font-weight
font-style: $font-style

// Chrome for Windows rendering fix: http://www.adtrak.co.uk/blog/font-face-chrome-rendering/
@media screen and (-webkit-min-device-pixel-ratio: 0)
@font-face
font-family: $font-family
src: url('#{$file-path}.svg##{$font-family}') format('svg')

@edkf

This comment has been minimized.

Show comment
Hide comment
@edkf

edkf Jan 27, 2017

Helpful. Thanks!

edkf commented Jan 27, 2017

Helpful. Thanks!

@rahulraguvanshi

This comment has been minimized.

Show comment
Hide comment
@rahulraguvanshi

rahulraguvanshi Feb 28, 2017

I used @include font-face("Font-Name", ../fonts/Font-Name, null);
Error: Invalid CSS after "fontname": expected expression

I used @include font-face("Font-Name", ../fonts/Font-Name, null);
Error: Invalid CSS after "fontname": expected expression

@Titoratus

This comment has been minimized.

Show comment
Hide comment
@Titoratus

Titoratus May 22, 2017

It works fine! Just DO NOT create .sass file, but .scss. Click "Download ZIP", import _mixins.scss into your folder, include it in main .sass file (@import '_mixins.scss' or @import 'mixins.scss' [it's no difference]). Then include your fonts.
For me it's not working — @include font-face(RobotoCondensed, fonts/RobotoCondensed);
But it works — @include font-face(RobotoCondensed, "../fonts/RobotoCondensed/RobotoCondensed", null, null, ttf woff woff2);
Notice that ttf has to be first!

It works fine! Just DO NOT create .sass file, but .scss. Click "Download ZIP", import _mixins.scss into your folder, include it in main .sass file (@import '_mixins.scss' or @import 'mixins.scss' [it's no difference]). Then include your fonts.
For me it's not working — @include font-face(RobotoCondensed, fonts/RobotoCondensed);
But it works — @include font-face(RobotoCondensed, "../fonts/RobotoCondensed/RobotoCondensed", null, null, ttf woff woff2);
Notice that ttf has to be first!

@mattmartini

This comment has been minimized.

Show comment
Hide comment
@mattmartini

mattmartini Jun 8, 2017

To make this work with asset pipeline in Rails 4.2 I changed url to font-url.

$src: append($src, font-url(quote($path + "." + $extmod)) format(quote($format)), comma);

To make this work with asset pipeline in Rails 4.2 I changed url to font-url.

$src: append($src, font-url(quote($path + "." + $extmod)) format(quote($format)), comma);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment