Instantly share code, notes, and snippets.

Embed
What would you like to do?
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?

WhiteBeetle commented 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?

@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?

Leaderproxima commented 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?

@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");

inseldesign commented Dec 13, 2015

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 "{")

DerExilant commented 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 "{")

@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

anup04sust commented 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

@mamsoudi

This comment has been minimized.

Show comment
Hide comment
@mamsoudi

mamsoudi Mar 18, 2016

Thank you for the mixin! Works perfectly!

mamsoudi commented Mar 18, 2016

Thank you for the mixin! Works perfectly!

@fabiowitt

This comment has been minimized.

Show comment
Hide comment
@fabiowitt

fabiowitt commented Mar 30, 2016

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

vishalPGit commented Jun 9, 2016

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?

surayashivji commented 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?

@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

rahulraguvanshi commented Feb 28, 2017

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!

Titoratus commented 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!

@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);

mattmartini commented 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);

@elliottmangham

This comment has been minimized.

Show comment
Hide comment
@elliottmangham

elliottmangham Aug 22, 2018

Anyone managed to rewrite this in PostCSS?

elliottmangham commented Aug 22, 2018

Anyone managed to rewrite this in PostCSS?

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