71

I have the following CSS - how would I describe it in SASS? I've tried reverse compiling it with css2sass, and just keep getting errors.... is it my CSS (which works ;-) )?

@font-face {
  font-family: 'bingo';
    src: url("bingo.eot");
    src: local('bingo'),
       url("bingo.svg#bingo") format('svg'),
       url("bingo.otf") format('opentype');
}
Dycey
  • 4,767
  • 5
  • 47
  • 86

4 Answers4

72

In case anyone was wondering - it was probably my css...

@font-face
  font-family: "bingo"
  src: url('bingo.eot')
  src: local('bingo')
  src: url('bingo.svg#bingo') format('svg')
  src: url('bingo.otf') format('opentype')

will render as

@font-face {
  font-family: "bingo";
  src: url('bingo.eot');
  src: local('bingo');
  src: url('bingo.svg#bingo') format('svg');
  src: url('bingo.otf') format('opentype'); }

which seems to be close enough... just need to check the SVG rendering

Dycey
  • 4,767
  • 5
  • 47
  • 86
51

I’ve been struggling with this for a while now. Dycey’s solution is correct in that specifying the src multiple times outputs the same thing in your css file. However, this seems to break in OSX Firefox 23 (probably other versions too, but I don’t have time to test).

The cross-browser @font-face solution from Font Squirrel looks like this:

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

To produce the src property with the comma-separated values, you need to write all of the values on one line, since line-breaks are not supported in Sass. To produce the above declaration, you would write the following Sass:

@font-face
  font-family: 'fontname'
  src: url('fontname.eot')
  src: url('fontname.eot?#iefix') format('embedded-opentype'), url('fontname.woff') format('woff'), url('fontname.ttf') format('truetype'), url('fontname.svg#fontname') format('svg')
  font-weight: normal
  font-style: normal

I think it seems silly to write out the path a bunch of times, and I don’t like overly long lines in my code, so I worked around it by writing this mixin:

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

Usage: For example, I can use the previous mixin to setup up the Frutiger Light font like this:

+font-face('frutigerlight', '../fonts/frutilig-webfont', 'frutigerlight')
Jezen Thomas
  • 13,619
  • 6
  • 53
  • 91
  • 1
    Interesting! My intranet users aren't using FF so hasn't noticed the issue. Will look into it – Dycey Sep 07 '13 at 14:41
  • 3
    I ran into an issue where the accepted solution wasn't working in IE9 and 10, but your suggestion to put all of the `src`s on one line fixed it. Thanks! – Steve Grossi Nov 11 '13 at 21:31
  • 1
    im getting this error Invalid CSS after " src: ": expected "{", was "url('#{$path}.e..." – Yehia A.Salam Sep 23 '14 at 23:21
  • @Jezen Thomas Your example include path, but doesn't include font-family `url('#{$path}.eot')` result: `src: url('#{../fonts/frutilig-webfont.eot')` Please fix – eugene_vandar Feb 04 '22 at 12:49
8

For those looking for an SCSS mixin instead, including woff2, SASS list.append is useful for conditionally adding source files/formats:

@mixin fface(
  $path,
  $family,
  $type: "",
  $weight: 400,
  $style: normal,
  $local1: null,
  $local2: null,
  $ttf: null,
  $otf: null,
  $eot: null,
  $svg: null
) {
  $src: null; // initialize an empty source path
  // only load local files when both sources are present
  @if $local1 and $local2 {
    $src: append($src, local("#{$local1}"), comma);
    $src: append($src, local("#{$local2}"), comma);
  }

  @if $otf {
    $src: append($src, url("#{$path}#{$type}.otf") format("opentype"), comma);
  }

  // load default formats (woff and woff2)
  $src: append($src, url("#{$path}#{$type}.woff2") format("woff2"), comma);
  $src: append($src, url("#{$path}#{$type}.woff") format("woff"), comma);
  // formats that should only be added at the end
  @if $ttf {
    $src: append($src, url("#{$path}#{$type}.ttf") format("truetype"), comma);
  }

  @if $svg {
    $src: append($src, url("#{$path}#{$type}.svg##{$svg}") format("svg"), comma);
  }
  // the actual FONT FACE DECLARATION
  @font-face {
    font-family: $family;
    // for compatibility reasons EOT comes first and is not appended
    @if $eot {
      src: url("#{$path}#{$type}.eot");
    }
    // load appended sources path
    src: $src;
    font-weight: $weight;
    font-style: $style;
  }
}
// USAGE
$dir: "assets/fonts/";

// declare family name
$familyName: "MyFont";

@include fface(
  "#{$dir}#{$familyName}", $familyName, "-regular", 400, "normal",
  "#{$familyName} Regular", "#{$familyName}-Regular", "ttf", "otf"
);

@include fface(
  "#{$dir}#{$familyName}", $familyName, "-medium", 500, "normal",
  "#{$familyName} Medium", "#{$familyName}-Medium", "ttf", "otf"
);

@include fface(
  "#{$dir}#{$familyName}", $familyName, "-semibold", 600, "normal",
  "#{$familyName} SemiBold", "#{$familyName}-SemiBold", "ttf", "otf"
);

// Material Icons
$familyName: "Material Icons"; // override previous value
$familyFileName: "MaterialIcons";

@include fface(
  "#{$dir}#{$familyFileName}", $familyName, "-regular", 400, "normal",
  $familyName, "#{$familyFileName}-Regular", "ttf", null, "eot"
);
@include fface(
  "#{$dir}#{$familyFileName}", "#{$familyName} Outline", "-outline", 400, "normal",
  "#{$familyName} Outline", "#{$familyFileName}-Outline", null, "otf", "eot"
);

.material-icons {
  font-family: $familyName;
}

.material-icons-outline {
  font-family: "#{$familyName} Outline";
}

The $type parameter is used for locating different files within a $family.

If you get a can't resolve error, remember to double check your fonts directory ($dir).

CPHPython
  • 12,379
  • 5
  • 59
  • 71
2

In my case I use SASS Mixin:

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

Usage:

@include font-face('altivo', 'altivo-regular', '', 'altivo-regular')
@include font-face('altivo', 'altivo-medium', '', 'altivo-medium', 500, normal)
@include font-face('altivo', 'altivo-bold', '', 'altivo-bold', 700, normal)
@include font-face('corsa', 'corsa-grotesk-regular', '', 'corsa-grotesk-regular')
@include font-face('corsa', 'corsa-grotesk-medium', '', 'corsa-grotesk-medium', 500, normal)
@include font-face('corsa', 'corsa-grotesk-bold', '', 'corsa-grotesk-bold', 700, normal)
@include font-face('corsa', 'corsa-grotesk-xbold', '', 'corsa-grotesk-xbold', 800, normal)

Result:

@font-face {
  font-family: "altivo";
  src: url("altivo-regular.eot");
  src: url("altivo-regular.eot?#iefix") format("embedded-opentype"), url("altivo-regular.woff") format("woff"), url("altivo-regular.ttf") format("truetype"), url("altivo-regular.svg#altivo-regular") format("svg");
  font-weight: normal;
  font-style: normal;
}
@font-face {
  font-family: "altivo";
  src: url("altivo-medium.eot");
  src: url("altivo-medium.eot?#iefix") format("embedded-opentype"), url("altivo-medium.woff") format("woff"), url("altivo-medium.ttf") format("truetype"), url("altivo-medium.svg#altivo-medium") format("svg");
  font-weight: 500;
  font-style: normal;
}
@font-face {
  font-family: "altivo";
  src: url("altivo-bold.eot");
  src: url("altivo-bold.eot?#iefix") format("embedded-opentype"), url("altivo-bold.woff") format("woff"), url("altivo-bold.ttf") format("truetype"), url("altivo-bold.svg#altivo-bold") format("svg");
  font-weight: 700;
  font-style: normal;
}
@font-face {
  font-family: "corsa";
  src: url("corsa-grotesk-regular.eot");
  src: url("corsa-grotesk-regular.eot?#iefix") format("embedded-opentype"), url("corsa-grotesk-regular.woff") format("woff"), url("corsa-grotesk-regular.ttf") format("truetype"), url("corsa-grotesk-regular.svg#corsa-grotesk-regular") format("svg");
  font-weight: normal;
  font-style: normal;
}
@font-face {
  font-family: "corsa";
  src: url("corsa-grotesk-medium.eot");
  src: url("corsa-grotesk-medium.eot?#iefix") format("embedded-opentype"), url("corsa-grotesk-medium.woff") format("woff"), url("corsa-grotesk-medium.ttf") format("truetype"), url("corsa-grotesk-medium.svg#corsa-grotesk-medium") format("svg");
  font-weight: 500;
  font-style: normal;
}
@font-face {
  font-family: "corsa";
  src: url("corsa-grotesk-bold.eot");
  src: url("corsa-grotesk-bold.eot?#iefix") format("embedded-opentype"), url("corsa-grotesk-bold.woff") format("woff"), url("corsa-grotesk-bold.ttf") format("truetype"), url("corsa-grotesk-bold.svg#corsa-grotesk-bold") format("svg");
  font-weight: 700;
  font-style: normal;
}
@font-face {
  font-family: "corsa";
  src: url("corsa-grotesk-xbold.eot");
  src: url("corsa-grotesk-xbold.eot?#iefix") format("embedded-opentype"), url("corsa-grotesk-xbold.woff") format("woff"), url("corsa-grotesk-xbold.ttf") format("truetype"), url("corsa-grotesk-xbold.svg#corsa-grotesk-xbold") format("svg");
  font-weight: 800;
  font-style: normal;
}
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Feb 04 '22 at 15:34