La regla CSS @font-face permite definir una tipografía e importarla para su uso en una página web. Antes de su existencia se podía definir una lista de familias en orden decreciente de prioridad con la regla font-family y se utilizaría la primera que el usuario tuviera instalada en su sistema, con font-face la fuente elegida se puede descargar y utilizar sin necesidad que el usuario disponga de ella con anteriordad.

La regla @font-face se asocia típicametne a CSS3 pero muy pocos se acuerdan de que estaba disponible en CSS2, aunque sus limitaciones, principalmente en los formatos aceptados, hacían que apenas se usase. La principal actualización de esta regla en CSS3 fue precisamente la de aceptar más formatos, como .eot, .ttf, .otf y .svg, lo que hizo posible un soporte más universal entre navegadores.

Sintaxis

La sintaxis de font-face es ls la siguiente:

@font-face{
    font-family:<nombre_de_la_fuente>;
    src: url(<ruta_url>) [format()][,url(<ruta_url>) [format()]]*;
    [font-weight:<weight>];
    [font-style:<estilo>];
    [font-stretch]:<stretch>];
    [unicode-range]:<range>];
}

Propiedades obligatorias

font-family

Es el nombre de la fuente y es el mismo que luego se definirá como valor en para la regla font-family en el elemento que deseemos utilizarla. Debería ir entre dobles comillas o comilla simple aunque si el nombre no contiene espacios puede escribirse sin comillas.

src

Se ha de definir al menos una URL dónde está ubicado el archivo de la fuente para poder importarla. Se pueden especificar varias rutas, cada una en una declaración url() y separada por una coma de la siguiente. Esto es útil para definir la ubicación de la misma fuente en diversos formatos y así maximizar la compatibilidad entre navegadores.

Recuerda que las declaraciones url() admiten URLs parciales o absolutas y que las parciales se interpretan de forma relativa al stylesheet, no al documento HTML.

También admite la declaración local('nombre fuente') para decirle al navegador que intente buscar entre las fuentes locales antes de descargar el archivo y ahorrar así tiempo y ancho de banda.

Ejemplo

<style>
@font-face {
  font-family: 'Cabin';
  /* Antes de descargar el archivo, le decimos al buscador
  que intente buscar en local la fuente con nombre
  Cabin, Cabin Regular o Cabin-Regular */
  src: local('Cabin'),
       local('Cabin Regular'),
       local('Cabin-Regular'),
       url(cabin-regular.woff) format('woff');
}

.cabin {
    font-family: 'Cabin';
}
</style> 

<p class="cabin">Estas letras se mostrarán en la fuente "Cabin"</p>

Propiedades opcionales

font-weight

Peso o fuerza de la fuente a utilizar. Puede ser normal, bold o los números 100, 200, 300, 400, 500, 600, 700, 900. El valor por defecto es normal.

font-style

Define como se va a estilizar la fuente. Puede ser normal, italic, oblique. El valor por defecto es normal.

font-stretch

Define como se a “estirar” la fuente. Puede ser: normal, condensed, ultra-condensed, extra-condensed, semi-condensed, expanded, semi-expanded, extra-expanded, ultra-expanded. El valor por defecto es normal.

unicode-range

Define el rango unicode soportado. Por defecto es “U+0-10FFFF”.

Ejemplo de sintaxis completo

@font-face {
    font-family: 'icomoonregular';
    src: local('icomoonregular'),
         url('icomoon-webfont.eot?#iefix') format('embedded-opentype'),
         url('icomoon-webfont.woff') format('woff'),
         url('icomoon-webfont.ttf') format('truetype'),
         url('icomoon-webfont.svg#icomoonregular') format('svg');
    font-weight: normal;
    font-style: normal;
    font-strecht: condensed;
    unicode-range: "U+0-10FFFF";
}

Formatos de archivo y compatibilidad entre navegadores

@font-face es soportado por todos los navegadores, incluso versiones bastantes antiguas, pero no todos los navegadores admiten la fuente en los mismos formatos. Por ejemplo, Internet Explorer por debajo de la versión 9 sólo admite formato OET (Embedded Open Type) y a partir de la versión 9 soporta los formatos WOFF y TTF/OTF. Por otro lado, ninguno de los demás principales navegadores soporta fuentes OET.

Para solucionar esto se suele recomendar declarar un lista de ubicaciones con la misma fuente en distintos formatos, de modo que cada navegador utilice la que pueda. Si sólo dispones de la fuente en un formato puedes utilizar cualquiera de las múltiples herramientas gratuitas de conversión, por ejemplo font2web.com. Hay que tener en cuenta que la ubicación del formato OET ha de ir la primera, ya que IE cargará el archivo de la primera ubicación que encuentre aunque sea de un formato que no soporte. Un ejemplo de font-face con máxima compatibilidad entre navegadores:

@font-face {
    font-family: 'Open Sans';
    src: url('open-sans.eot');
    src: local('icomoonregular'),
         url('open-sans.eot?#iefix') format('embedded-opentype'),
         url('open-sans.woff') format('woff'),
         url('open-sans.ttf') format('truetype'),
         url('open-sans.svg#open-sans') format('svg');
}

Si no estás interesado en dar soporte a Internet Explorer por debajo de la versión 9 puedes optar por utilizar sólo los formatos WOFF, que soportados por todos los navegadores desde versiones relativamente tempranas. Algunos servicios de webfonts, como Google Fonts, ofrecen únicamente formato WOFF o WOFF2:

@font-face {
    font-family: 'Open Sans';
    src: url('open-sans.eot');
    src: local('icomoonregular'),
         url('open-sans.woff') format('woff'),
         url('open-sans.woff2') format('woff2');
}

Algunos ejemplos más

Imaginemos que vamos a utilizar dos fuentes, la fuente Raleway en dos variantes, normal e italic, más la fuente Bungee Inline. Hay que hacer un font-face por cada variante, así que en total tendríamos que hacer tres font-face:

@font-face {
    font-family: 'Raleway';
    font-style: normal;
    font-weight: 400;
    src: local('Raleway'), local('Raleway-Regular'), url(https://fonts.gstatic.com/s/raleway/v11/0dTEPzkLWceF7z0koJaX1A.woff2) format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
}

@font-face {
    font-family: 'Raleway';
    font-style: italic;
    font-weight: 400;
    src: local('Raleway Italic'), local('Raleway-Italic'), url(https://fonts.gstatic.com/s/raleway/v11/IIm-lPOtfVKQy0GMiczF_1tXRa8TVwTICgirnJhmVJw.woff2) format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
}

@font-face {
    font-family: 'Bungee Inline';
    font-style: normal;
    font-weight: 400;
    src: local('Bungee Inline'), local('BungeeInline-Regular'), url(https://fonts.gstatic.com/s/bungeeinline/v2/Tb-1914q4rFpjT-F66PLCTxObtw73-qQgbr7Be51v5c.woff2) format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
}

Ahora, podríamos utilizar Raleway normal para todo el <body> y crear selectores CSS para elementos en los que queramos utilizar las otras tipografías:

body {
  font-family: 'Raleway';
  front-style: normal;
  font-weight: 400;
}

.rlw-italic {
  font-family: 'Raleway';
  front-style: italic;
  font-weight: 400;
}

.bungee {
  font-family: 'Bungee Inline';
  font-style: normal;
  font-weight: 400;
}

Pero, como las propiedades CSS se heredan, el código anterior se podría quedar en:

body {
  font-family: 'Raleway';
  front-style: normal;
  font-weight: 400;
}

.rlw-italic {
  /* Hereda font-family y font-weight del body */
  font-style: italic;
}

.bungee {
  /* Hereda font-style y font-weight del body */
  font-family: 'Bungee Inline';
}

Demo

  • Juan Carlos Yaya

    Muy buenas tardes/noches. Gracias por compartir sus conocimientos. Quisiera saber si existe alguna forma de convertir el formato WOFF2 a TTF. Tengo muchos archivos Woff2 y no se como usarlos n mis programas de Adobe. Gracias.

  • Nestor Fontalvo

    Excelente sitio…felicitaciones…este código lo pegue en un widget editor de site origin pero no me funciono…
    Dentro del widget:
    https://uploads.disquscdn.com/images/4d1b745ce6b7de19b1937394577265f831fb698065dae71fd1c0377be4aeac6c.jpg
    Resultado: https://uploads.disquscdn.com/images/d1b03fdd9fd83f04bea0f3fa695eaf6204981bd8dccf8cfc54b6aab5ded6edeb.jpg

    • Así sin más, no te puedo decir, ¿has comprobado el código generado en el frontend?

  • Rocío Trigo

    Hola Juan.
    Antes de nada: gracias por toda esta información! Es uno de los sitios que más claros me han parecido para entender todo esto.
    Estoy estudiando este tema y me surge una duda, a ver si sabes darme solución. Quiero usar varios estilos de una fuente de Google Fonts, pongamos por caso: light, medium, bold y black-italic. ¿Cómo debería hacerse esto? Ya que si creo un @font-face para cada estilo… hastaluegolucas que ya si que no hay manera… ¿Debería usar font-weight en el css? ¿Esto respetaría la fuente y sus estilos?
    Espero que podáis ayudarme. Muchísimas gracias por todo

    • Pues sí, tienes que crear un font-face para cada variante de la fuente tipográfica, en tu caso cuatro.

      Fíjate que, al ser variantes de la misma fuente, font-family tiene el mismo valor en todos los font-face. Por ejemplo, el siguiente código sería el font-face para la fuente Raleway estilo normal y estilo italic:

      @font-face {
      font-family: 'Raleway';
      font-style: normal;
      font-weight: 400;
      src: local('Raleway'), local('Raleway-Regular'), url(https://fonts.gstatic.com/s/raleway/v11/0dTEPzkLWceF7z0koJaX1A.woff2) format('woff2');
      unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
      }
      @font-face {
      font-family: 'Raleway';
      font-style: italic;
      font-weight: 400;
      src: local('Raleway Italic'), local('Raleway-Italic'), url(https://fonts.gstatic.com/s/raleway/v11/IIm-lPOtfVKQy0GMiczF_1tXRa8TVwTICgirnJhmVJw.woff2) format('woff2');
      unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
      }

      Luego, por poner un ejemplo, podemos asignar el estilo normal al <body> y el estilo italic al elemento <i> y al selector .italic:

      body {
      font-family: Raleway;
      font-style: normal;
      font-weight: 400;
      }

      i, .italic {
      font-family: Raleway;
      font-style: italic;
      font-weight: 400;
      }

      Aunque en realidad, como el elemento <i> y el selector .italic estarían dentro del <body> y heredan sus propiedades, solo sería necesario cambiar la propiedad font-style:

      body {
      font-family: Raleway;
      font-style: normal;
      font-weight: 400;
      }

      i, .italic {
      font-style: italic;
      }

      Espero que ahora lo entiendas un poco mejor.

  • balpizar

    Buenas, vieras que tengo un problema.
    Tengo un sitio con varias páginas y he creado una fuente en ‘icomoon’.
    Esta me funciona a la perfección en el index, pero en otras páginas que tengo dentro de una carpeta llamada “html” no me funcionan en todos los navegadores, solamente en en chrome.
    Si alguien me puede ayudar, le agradezco.

    • ¿Puedes poner el CSS que estás utilizando y como lo cargas en el HTML? Así sin ver el código y con la información que das no te puedo decir.