nonopolarity
nonopolarity

Reputation: 151186

In CSS @font-face, the font-weight is not to specify what weight to use for this font, but to "match" with the 3 categories of font-weight?

Let's say we define a font-family to use by using @font-face:

@font-face {
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 900;
  src: local('Roboto'), local('Roboto-Regular'), url(https://fonts.gstatic.com/s/roboto/v15/oMMgfZMQthOryQo9n22dcuvvDin1pK8aKteLpeZ5c0A.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;
}

It seems that the font-weight above is not to specify what weight to present using this font file if the user specifies font-family: Roboto, but rather, it is "to match" which font file to use when the @font-face specifies the same name.

Example:

If inside of @font-face, we specify a font-weight of 400, now the text is presented in Google Chrome (version 48.0, and I can get almost identical results for jsfiddles in this question using the current Firefox 44.0.2), with the light not being able to be lighter, but the bold one is probably made bold by rendering tricks of "double printing" font or "double width" of a pixel:

https://jsfiddle.net/0vL8m9bj/

If we make the font-weight is made to 900 in @font-face, then all 3 lines of text becomes regular:

https://jsfiddle.net/0vL8m9bj/1/

So we can see that the 900 is not to specify what to show, using that font file.

So what is the use of font-weight inside of @font-face?

If we use https://www.google.com/fonts#UsePlace:use/Collection:Roboto and link this line:

<link href='https://fonts.googleapis.com/css?family=Roboto:400,700,900,300' 
    rel='stylesheet' type='text/css'>

This will actually load some CSS definitions as a file into the browser:

/* latin */
@font-face {
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 300;
  src: local('Roboto Light'), local('Roboto-Light'), url(https://fonts.gstatic.com/s/roboto/v15/Hgo13k-tfSpn0qi1SFdUfZBw1xU1rKptJj_0jans920.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;
}

/* latin */
@font-face {
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 400;
  src: local('Roboto'), local('Roboto-Regular'), url(https://fonts.gstatic.com/s/roboto/v15/oMMgfZMQthOryQo9n22dcuvvDin1pK8aKteLpeZ5c0A.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;
}

/* latin */
@font-face {
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 900;
  src: local('Roboto Black'), local('Roboto-Black'), url(https://fonts.gstatic.com/s/roboto/v15/mnpfi9pxYH-Go5UiibESIpBw1xU1rKptJj_0jans920.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;
}
/* other languages omitted here */

Now we can see the 3 "weights":

https://jsfiddle.net/0vL8m9bj/5/

but, it is not by closest match by the number -- it looks like it is match by "light", "normal", and "bold" category, because if it is a 301, it will not match with 299, even thought it is very close to 299, but will match with the 400 or 500:

https://jsfiddle.net/0vL8m9bj/6/

The 699 also won't match with 700, but will match with 400.

We can also see that, if we reverse the @font-face's font-weight, and use bold, normal, lighter for the styles of the text, then bold will use the light font file, and lighter will use the dark font file:

https://jsfiddle.net/0vL8m9bj/10/

However, one strange thing is that, if the 700 is changed in the last @font-face to 701, now all 3 lines will become bold:

https://jsfiddle.net/0vL8m9bj/7/

So it is really strange. It seems the rule is: match with the 3 categories of weights, except the last example.

One more strange thing: if .section1 is font-weight: 300, it show as light:

https://jsfiddle.net/0vL8m9bj/8/

but make it font-weight: 299 -- meaning lighter, now it appears as bold:

https://jsfiddle.net/0vL8m9bj/9/

So making it lighter made it bold.

So what is the rule of font-weight inside @font-face?

Upvotes: 4

Views: 1868

Answers (2)

Diogo S
Diogo S

Reputation: 11

I was also intrigued by how the @font-face was being selected based on the style's font-weight but this MDN article explained it very clearly https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight#fallback_weights

I was also testing it myself with

body {
  font-family: 'Averta', sans-serif;
}

@font-face {
  font-family: 'Averta';
  src: url('../public/fonts/averta-regular-webfont.woff2') format('woff2');
  font-weight: normal;
  font-style: normal;
}

@font-face {
  font-family: 'Averta';
  src: url('../public/fonts/averta-bold-webfont.woff2') format('woff2');
  font-weight: bold;
  font-style: normal;
}

and proved that

<div style={{ fontWeight: 501 }}>Balance:</div>

will display the bold font

while

<div style={{ fontWeight: 500 }}>Balance:</div>

will display the regular font

Upvotes: 1

user6024442
user6024442

Reputation: 21

Your hypothesis is correct.

The descriptors inside a @font-face do not correlate to styling of elements, only to font matching. From the CSS Fonts Module Level 3 draft:

[4.1] The @font-face rule allows for linking to fonts that are automatically fetched and activated when needed. This allows authors to select a font that closely matches the design goals for a given page rather than limiting the font choice to a set of fonts available on a given platform. A set of font descriptors define the location of a font resource, either locally or externally, along with the style characteristics of an individual face.

...

Each @font-face rule specifies a value for every font descriptor, either implicitly or explicitly. Those not given explicit values in the rule take the initial value listed with each descriptor in this specification. These descriptors apply solely within the context of the @font-face rule in which they are defined, and do not apply to document language elements. There is no notion of which elements the descriptors apply to or whether the values are inherited by child elements.

Then later under section 4.4:

[font-style, font-weight and font-stretch] define the characteristics of a font face and are used in the process of matching styles to specific faces. For a font family defined with several @font-face rules, user agents can either download all faces in the family or use these descriptors to selectively download font faces that match actual styles used in document. The values for these descriptors are the same as those for the corresponding font properties except that relative keywords are not allowed, ‘bolder’ and ‘lighter’. If these descriptors are omitted, initial values are assumed.

...

The advantage of this is that one does not need font-family names for "RobotoBold", "RobotoLight", etc.

Upvotes: 2

Related Questions