249

I have to import the Klavika font and I've received it in multiple shapes and sizes:

Klavika-Bold-Italic.otf
Klavika-Bold.otf
Klavika-Light-Italic.otf
Klavika-Light.otf
Klavika-Medium-Italic.otf
Klavika-Medium.otf
Klavika-Regular-Italic.otf
Klavika-Regular.otf

Now I would like to know if it's possible to import those into CSS with just one @font-face-query, where I'm defining the weight in the query. I want to avoid copy/pasting the query 8 times.

So something like:

@font-face {
  font-family: 'Klavika';
  src: url(../fonts/Klavika-Regular.otf), weight:normal;
  src: url(../fonts/Klavika-Bold.otf), weight:bold;
}
Rvervuurt
  • 8,589
  • 8
  • 39
  • 62
  • 5
    It's not 1 font...it's multiple fonts...so unfortunately, I think you'd have to just grin and bear it. – Paulie_D Feb 02 '15 at 14:33
  • Yea sorry, it's different fonts within the same family. – Rvervuurt Feb 02 '15 at 14:34
  • Multiple webfont-files === different weights – Eric Feb 02 '15 at 14:39
  • 2
    this article might help: http://www.456bereastreet.com/archive/201012/font-face_tip_define_font-weight_and_font-style_to_keep_your_css_simple/ actually there is an SO Answer here: http://stackoverflow.com/questions/10045859/how-to-use-font-weight-with-font-face-fonts that uses that article, an alternative to what you want as what you want is not possible. – 97ldave Feb 03 '15 at 11:35

6 Answers6

538

Actually there is a special flavor of @font-face that will permit just what you're asking.

Here's an example using the same font-family name with different styles and weights associated with different fonts:

@font-face {
  font-family: "DroidSerif";
  src: url("DroidSerif-Regular-webfont.ttf") format("truetype");
  font-weight: normal;
  font-style: normal;
}

@font-face {
  font-family: "DroidSerif";
  src: url("DroidSerif-Italic-webfont.ttf") format("truetype");
  font-weight: normal;
  font-style: italic;
}

@font-face {
  font-family: "DroidSerif";
  src: url("DroidSerif-Bold-webfont.ttf") format("truetype");
  font-weight: bold;
  font-style: normal;
}

@font-face {
  font-family: "DroidSerif";
  src: url("DroidSerif-BoldItalic-webfont.ttf") format("truetype");
  font-weight: bold;
  font-style: italic;
}

You can now specify font-weight:bold or font-style:italic to any element you like without having to specify the font-family or overriding font-weight and font-style.

body { font-family:"DroidSerif", Georgia, serif; }

h1 { font-weight:bold; }

em { font-style:italic; }

strong em {
  font-weight:bold;
  font-style:italic;
}

For a full overview of this feature and the standard use take a look at this article.


EXAMPLE PEN

diogo
  • 3,769
  • 1
  • 24
  • 30
maioman
  • 18,154
  • 4
  • 36
  • 42
  • This is cool! Will implement it this way, because working with different font-names gets confusing at times, when it's in basics the same font. – Rvervuurt Feb 05 '15 at 11:11
  • 1
    just as I suggested in my comment above ;-) – 97ldave Feb 06 '15 at 16:53
  • 16
    In my case, this only use the lowest @font-face. That would be font-weight: bold; font-style: italic; everytime I refer to font-family: 'DroidSerif'; – Simon Arnold Feb 12 '16 at 18:53
  • Would this trick be working for other extensions like .woff, .svg, .eot or woff2 too? Could you share working JSFIDDLE? – Kushal Jayswal Jul 28 '16 at 15:22
  • 1
    Do you have a test that proves this method is actually working? How would you prove that the browser isn't just faking the weight or style without reading the correct font file? – rojobuffalo Oct 13 '16 at 02:28
  • 1
    @rojobuffalo [here's](http://codepen.io/maio/pen/rrKKjA) an example pen, it's working like expected. – maioman Oct 13 '16 at 09:39
  • 1
    FYI if you have a bunch of font styles with names like "book" or "black" or "medium", etc., you can map those to the numerical `font-weight` values (e.g. `100`, `200`, `300`) since those style names aren't available values for `font-weight`. – evolross Mar 04 '17 at 22:09
  • 3
    @rojobuffalo makes a very valid point. The pen does nothing to verify the validity of the assertion that this will behave as expected. Specifically, I removed the bold font-face declaration from the CSS example and ran it again. The appearance was identical. Was it pulling from cache? Was the browser simply fiddling the displayed weight of the regular font? –  Mar 26 '17 at 10:40
  • @SimonArnold also makes a good point that some browsers which do not support font-face, or do so incorrectly or incompletely, may view subsequent declarations as re-declarations, clobbering the previous, so that only the last is used. –  Mar 26 '17 at 10:41
  • @user314159 the pen is working fine, if you remove `font-weight:bold;` font-face declaration falls back as expected. – maioman Mar 26 '17 at 13:20
  • 1
    @rojobuffalo That is exactly the case. I have tested it with multiple fonts and the outcome is not the same. The browser is just faking the weight and style of the initial font. If you work with a graphic designer on frontend developing, expecting pixel perfect results, I do not recommend using this method. – fat_mike Dec 30 '18 at 16:07
  • 3
    This method is correct and is outlined in this Mozilla article: https://hacks.mozilla.org/2009/06/beautiful-fonts-with-font-face/. You can tell the pen is working because it's defined the 'bold' font as an italic font. If the browser were faking it, it would appear bold, but it appears italic as expected. This method also has the advantage that it would style fallback fonts correctly, because `font-weight: bold` (or whatever) is used alongside the `font-family` declaration. – nabrown Oct 03 '19 at 15:38
14
@font-face {
  font-family: 'Klavika';
  src: url(../fonts/Klavika-Regular.otf) format('truetype') font-weight-normal,
       url(../fonts/Klavika-Bold.otf) format('truetype') font-weight-bold,
       url(../fonts/Klavika-Bold-Italic.otf) format('truetype') font-italic font-weight-bold;
}
Mirka Nimsová
  • 285
  • 2
  • 3
8

Update 2022: use variable fonts

Provided your font is available as a variable font you can actually combine multiple font-weights in a single @font-face rule like so:

@font-face {
  font-family: 'Roboto Flex';
  font-style: normal;
  font-weight: 100 1000;
  font-stretch: 0% 200%;
  src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXpRJ6cXW4O8TNGoXjC79QRyaLshNDUf9-EmFw.woff2) format('woff2');
}

We need to specify a font-weight range by adding 2 values:

font-weight: 100 1000;

slider_weight.addEventListener("input", function () {
  var axisValue = slider_weight.value;
  testarea.style.fontWeight = axisValue;
  value_weight.innerText = axisValue;
});

slider_width.addEventListener("input", function () {
  var axisValue2 = slider_width.value;
  testarea.style.fontStretch = axisValue2+'%';
  value_width.innerText = axisValue2;
});
body{
  font-family: 'Roboto Flex';
  font-size:5vw
}


@font-face {
  font-family: 'Roboto Flex';
  font-style: normal;
  font-weight: 100 1000;
  font-stretch: 0% 200%;
  src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXpRJ6cXW4O8TNGoXjC79QRyaLshNDUf9-EmFw.woff2) format('woff2');
}


#testarea {
  font-size: 2em;
  transition:0.5s;
  font-weight:100;
  font-stretch: 0%;
}

.regular{
font-weight:400
}

.bold{
font-weight:900
}

.condensed{
font-stretch:0%;
}
<h1 class="bold">Roboto Flex bold</h1>
<h1 class="regular condensed">Roboto Flex regular condensed</h1>
  
  
  <label for="slider_weight">Weight</label>
  <input type="range" id="slider_weight" name="slider" value="100" min="100" max="1000" step="10">
  <span id="value_weight">100</span>
  <br>

  <label for="slider_width">Width</label>
  <input type="range" id="slider_width" name="slider" value="0" min="0" max="200" step="1">
  <span id="value_width">0</span>

<p id="testarea" contenteditable="true">Type something ...</p>

Retrieving google variable fonts ... tricky

I highly recommend this post, since the current google fonts UI isn't particularly helpful:
How To Get The Variable Font Links From Google Fonts?

Keep in mind the @font-face won't automatically apply font weights to emphasized elements like <strong> or <h1><h2><h3> etc.

So make sure, you specify the desired font weights for a predictable rendering like so:

/* Variable fonts: we can apply intermediate weight values - yay! */  
strong{
   font-weight: 623 
}

Don't rely on keyword-based weights or styles (e.g semi-bold, medium, semi-condensed etc.)

For instance: what is the difference between "medium" and "semibold"?
... It depends on the font design, your font's weight range and actually on your design decision.
Some fonts are by default rather "bold" others rather "thin" or "light" (related post: Some Google font doesn't have Semibold font type)

/* Roboto 400 is too bold for me – map default/regular weight 400 to 300 */  
body{
  font-family: "Roboto Flex";
  font-weight: 300;
}

/* Roboto 700 is not bold enough for me – map default/bold weight 700 to 1000*/  
strong{
  font-weight: 1000
}

/* ... OK a medium weight might be handy – lets say 625  */  
.medium{
  font-weight: 625
}

/* condensed or expanded styles: font-stretch < 100 = condensed; 
font-stretch > 100 = expanded; */
.condensed{
  font-stretch:0%;
}
.semi-condensed{
  font-stretch:50%;
}

.semi-expanded{
  font-stretch:200%;
}

.expanded{
  font-stretch:200%;
}
herrstrietzel
  • 11,541
  • 2
  • 12
  • 34
3

If like me you need to load Roboto fonts without hitting Google's servers it should look like:

/* Thin */
@font-face {
    font-family: 'Roboto';
    src: url(../fonts/Roboto-Thin.ttf) format('truetype');
    font-style: normal;
    font-weight: 100;
}

/* Light */
@font-face {
    font-family: 'Roboto';
    src: url(../fonts/Roboto-Light.ttf) format('truetype');
    font-style: normal;
    font-weight: 300;
}

/* Normal */
@font-face {
    font-family: 'Roboto';
    src: url(../fonts/Roboto-Regular.ttf) format('truetype');
    font-style: normal;    
    font-weight: 400;
}

/* Medium */
@font-face {
    font-family: 'Roboto';
    src: url(../fonts/Roboto-Medium.ttf) format('truetype');
    font-style: normal;
    font-weight: 500;
}

/* Bold */
@font-face {
    font-family: 'Roboto';
    src: url(../fonts/Roboto-Bold.ttf) format('truetype');
    font-style: normal;    
    font-weight: 700;
}

/* Black */
@font-face {
    font-family: 'Roboto';
    src: url(../fonts/Roboto-Black.ttf) format('truetype');
    font-style: normal;
    font-weight: 900;
}

Then do the same for the italic variants if needed. See font-weight documentation for clues on mapping names to numerical weight. Here is Roboto font downlond link.

Slion
  • 2,558
  • 2
  • 23
  • 27
2

Use Tranfonter, saved me a ton of time: https://transfonter.org/

Kevin Parker
  • 16,975
  • 20
  • 76
  • 105
0

Solution for SCSS:

@mixin fontPoppins($name, $weight, $style) {
  @font-face {
    font-family: poppins;
    src: url('/assets/poppins/#{$name}.ttf') format("truetype");
    font-weight: $weight;
    font-style: $style;
  }
}

@include fontPoppins('Poppins-Thin', 100, normal);
@include fontPoppins('Poppins-ThinItalic', 100, italic);
@include fontPoppins('Poppins-ExtraLight', 200, normal);
@include fontPoppins('Poppins-ExtraLightItalic', 200, italic);
@include fontPoppins('Poppins-Light', 300, normal);
@include fontPoppins('Poppins-LightItalic', 300, italic);
@include fontPoppins('Poppins-Regular', normal, normal);
@include fontPoppins('Poppins-Italic', normal, italic);
@include fontPoppins('Poppins-Medium', 500, normal);
@include fontPoppins('Poppins-MediumItalic', 500, italic);
@include fontPoppins('Poppins-SemiBoldItalic', 600, italic);
@include fontPoppins('Poppins-Bold', bold, normal);
@include fontPoppins('Poppins-BoldItalic', bold, italic);
@include fontPoppins('Poppins-ExtraBold', 800, normal);
@include fontPoppins('Poppins-ExtraBoldItalic', 800, italic);
@include fontPoppins('Poppins-Black', 900, normal);
@include fontPoppins('Poppins-BlackItalic', 900, italic);

Where fonts expected to be in some static folder, in Angular it is assets folder.

currently I have in assets folder 18 files dowloaded from google fonts:

Poppins-Black.ttf
Poppins-BlackItalic.ttf
Poppins-Bold.ttf
Poppins-BoldItalic.ttf
Poppins-ExtraBold.ttf
Poppins-ExtraBoldItalic.ttf
Poppins-ExtraLight.ttf
Poppins-ExtraLightItalic.ttf
Poppins-Italic.ttf
Poppins-Light.ttf
Poppins-LightItalic.ttf
Poppins-Medium.ttf
Poppins-MediumItalic.ttf
Poppins-Regular.ttf
Poppins-SemiBold.ttf
Poppins-SemiBoldItalic.ttf
Poppins-Thin.ttf
Poppins-ThinItalic.ttf

What next?

Or add it to the global css file

@tailwind base;
@tailwind components;
@tailwind utilities;

body { margin: 0; }

html, body {
  height: 100%;
  font-family: poppins, sans-serif /* sans-serif is fallback */;
}

Or use it in HTML

Somewhere in html use style prop:

<p style='font-family: poppins, sans-serif; 
          font-weight: bold; 
          font-style: italic' >Some text</p>

where sans-serif it is fallback font in case of internet issues.

Or use it in Tailwind

<p style='font-family: poppins, sans-serif' 
   class='font-bold italic'>Some text</p>
Yuriy Gyerts
  • 1,464
  • 18
  • 30