Font Face Generator

Recentemente, converti um projeto de Ruby Sass and Compass para libsass. O mixin Compass font-faceestava sendo usado para produzir as @font-faceregras. Já que não queria ter que escrever @font-faceregras individuais para este projeto ou projetos futuros, decidi ver se poderia criar minha própria versão de um font-facemixin.

Aqui está o que eu inventei.

$ff-dir: '/fonts' !default;

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

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

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

Você chama ff-batchpara gerar mais de uma @font-faceregra. O mixin aceita um mapa Sass que contém todas as informações sobre as fontes que você está usando. Se você precisar de apenas uma @font-faceregra, é só usar o ff-singlemixin.

Acho que usar um mapa Sass para armazenar todas as informações da fonte, como o nome da fonte e seu peso, é muito mais fácil de manter do que muitas regras.@font-face

Aqui está um exemplo de como o mapa se parece.

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

A primeira chave no mapa, “Proxima-Nova”, é o nome da sua fonte. Esse valor pode ser o que você quiser. Ele é usado como o valor da propriedade e permite que você aproveite os links de estilo . Desta forma, todos os estilos da fonte “Proxima-Nova”, como bold e italic, usam o mesmo valor de família de fontes.font-family

O valor para esse nome de família de fontes é a lista de mapas Sass. Cada entrada do mapa é um estilo e corresponde a uma regra. Portanto, o exemplo acima produzirá 5 regras. A única propriedade necessária é a propriedade. Este nome corresponde ao nome real do arquivo da fonte. Os formatos de fonte padrão são e e para peso e estilo os padrões são normais. Você pode substituir esses padrões fornecendo valores para as chaves, formato, peso e estilo. Para os formatos, você precisará usar uma lista dos formatos que deseja incluir. Todos os diferentes formatos de seu arquivo de fonte precisam ter o mesmo nome.@font-family@font-facenamewoffttf

Quando se trata de formatar o mapa, você pode usar aspas em torno das chaves e valores ou não. O mixin sempre produzirá o formato correto. Apenas certifique-se de que você é consistente. Para mim, uma vez que o formato do mapa é semelhante JSON, apenas sigo as regras de formato para JSON.

Uso

Então, usando o mapa Sass acima, você chama o mixin dessa forma.

@include ff-batch($ff-map);

E o CSS compilado sai assim.

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

Você pode chamar isso de mixin em qualquer lugar em seu Sass porque as regras serão geradas no nível raiz de seu CSS.@font-face

Se você sentir vontade, também pode ligar para a saída de uma única regra. Embora fará a mesma coisa se o seu mapa contiver uma única entrada.ff-single@font-faceff-batch

$icomoon-list:
url
("/fonts/icomoon.woff") format("woff"),
url
("/fonts/icomoon.ttf") format("ttf"),
url
("/fonts/icomoon.svg") format("svg");
// The 1st argument is the font-family and the second is a list of the font-file URLs.
// Weight and style are optional 3rd and 4th arguments respectively.
@include ff-single('icomoon', $icomoon-list);

Por padrão, o diretório de fontes está localizado em /fonts. Você pode substituir isso definindo uma variável chamada $ff-dir. Basta definir o valor dessa variável para a localização de seus arquivos de fonte.

Muito obrigado a Hugo Giraudel por me dar alguns bons conselhos sobre isso.

Você pode experimentar o mixin documentado no SassMeister .

Também há uma essência no github .