Title: CSS Fonts Module Level 4 Shortname: css-fonts Level: 4 Status: ED Prepare for TR: no Work Status: Revising Group: CSSWG ED: https://drafts.csswg.org/css-fonts-4/ TR: https://www.w3.org/TR/css-fonts-4/ Previous Version: https://www.w3.org/TR/2024/WD-css-fonts-4-20240201/ Former Editor: John Daggett, Invited Expert, https://twitter.com/nattokirai, w3cid 41498 Former Editor: Myles C. Maxfield, Formerly of Apple Inc., mmaxfield@apple.com, w3cid 77180 Editor: Chris Lilley, W3C, http://svgees.us, w3cid 1438 Abstract: This specification defines modifications to the existing CSS Fonts 3 specification along with additional features. At Risk: Synthesis of the 'font-variant-position' property At Risk: The 'font-language-override!!property' property At Risk: The 'font-language-override!!descriptor' descriptor Ignored Terms:Complain About: missing-example-ids true Default Highlight: css WPT Path Prefix: css/css-fonts/ WPT Display: closed
spec:css-color-4; type:property; text:color spec: css-color-5; type: type; text:spec:css-values; type:value; text:ex spec:css22; type:value; for:/; text:block spec:html; type:element; text:font spec:fetch; type:dfn; for:/; text:request spec:fetch; type:dfn; for:/; text:fetch
{ "GRAPHITE": { "href": "https://scripts.sil.org/cms/scripts/page.php?site_id=projects&item_id=graphite_techAbout", "title": "Graphite technical overview", "publisher": "SIL", "date": "2012" }, "PFE-report": { "href": "https://www.w3.org/TR/PFE-evaluation/", "authors": [ "Chris Lilley" ], "status": "Note", "publisher": "W3C", "title": "Progressive Font Enrichment: Evaluation Report", "date": "15 October 2020" } }
Name: font-family Value: [ <> | < > ]# Initial: depends on user agent Applies to: all elements and text Inherited: yes Percentages: n/a Computed value: list, each item a string and/or < > keywords Animation type: discrete
body { font-family: Helvetica, Verdana, sans-serif; }If Helvetica is available, it will be used when rendering. If neither Helvetica nor Verdana is present, then the generic font-family ''sans-serif'' font will be used.
Font family names other than generic families or system font families must either be given quoted as << = <> > | < >+
font-family: Red/Black, sans-serif; font-family: "Lucida" Grande, sans-serif; font-family: Ahem!, sans-serif; font-family: test@foo, sans-serif; font-family: #POUND, sans-serif; font-family: Hawaii 5-0, sans-serif;
font-family: "sans-serif", sans-serif; font-family: "default", sans-serif; font-family: "initial", sans-serif; font-family: "inherit", sans-serif;
body { font-family: "New Century Schoolbook", serif } <body style="font-family: '21st Century', fantasy">
< = generic( <> >+ ) | < > | < >+
body { font-family: "Adobe Fangsong Std R", generic(fangsong), serif}The first choice in this example is a specific, named font, in Fang Song (仿宋) style. The family name is enclosed in quotes as it contains space characters. The second is a recently added script-specific generic font; it is unicode-range specific and so may not match to an actual installed font on some systems; but if it exists it will be an example of the requested style. The third is a universal generic font, which is guaranteed to match on all systems.
< = caption | icon | menu | message-box | small-caption | status-bar>
<div id="system-text" style="font-family: system-ui"></div> ... window.getComputedStyle(document.getElementById("system-text")).getPropertyValue("font-family");The script above should not have any knowledge of how ''system-ui'' is expanded to include a collection of system user interface fonts. In particular, the above script should yield a result of "system-ui" on every platform.
Name: font-weight Value: <> | bolder | lighter Initial: normal Applies to: all elements and text Inherited: yes Percentages: n/a Computed value: a number, see below Animation type: by computed value type
<font-weight-absolute> = [normal | bold | <Values have the following meanings:>]
Inherited value (w) | bolder | lighter |
---|---|---|
w < 100 | 400 | No change |
100 ≤ w < 350 | 400 | 100 |
350 ≤ w < 550 | 700 | 100 |
550 ≤ w < 750 | 900 | 400 |
750 ≤ w < 900 | 900 | 700 |
900 ≤ w | No change | 700 |
wght
variation is used to implement varying weights.
Fractional weights are valid.
Although the practice is not well-loved by typographers,
bold faces are often synthesized by user agents for families that lack actual bold faces.
For the purposes of font matching,
these faces must be treated as if they exist within the family.
Authors can explicitly avoid this behavior by using the 'font-synthesis' property.
Name: font-width Value: normal | <> | ultra-condensed | extra-condensed | condensed | semi-condensed | semi-expanded | expanded | extra-expanded | ultra-expanded Initial: normal Applies to: all elements and text Inherited: yes Percentages: Not resolved Computed value: a percentage, see below Animation type: by computed value type
Absolute keyword value | Numeric value |
---|---|
ultra-condensed | 50% |
extra-condensed | 62.5% |
condensed | 75% |
semi-condensed | 87.5% |
normal | 100% |
semi-expanded | 112.5% |
expanded | 125% |
extra-expanded | 150% |
ultra-expanded | 200% |
wdth
variation is used to implement varying widths.
h1 {font-stretch: condensed; }The specified value of the 'font-width!!property' on those headings becomes set to ''condensed'''.
h1 {font-width: condensed; }The specified value of the 'font-stretch!!property' on those headings becomes set to ''condensed''.
Name: font-style Value: normal | italic | oblique <>? Initial: normal Applies to: all elements and text Inherited: yes Percentages: n/a Computed value: the keyword specified, plus angle in degrees if specified Animation type: by computed value type;''normal'' animates as ''oblique 0deg''
slnt
variation is used to implement oblique values,
and the ital
variation with a value of 1 is used to implement the italic values.
Note: the OpenType slnt
axis is defined
with a positive angle meaning a counter-clockwise slant,
the opposite direction to CSS.
The CSS implementation will take this into account
when using variations
to produce oblique faces.
Issue: What direction should positive and negative obliques skew in vertical writing mode?
How do we achieve skews in the opposite dimension
(needed for vertical writing)?
If no italic or oblique face is available,
oblique faces may be synthesized by rendering non-obliqued faces
with an artificial obliquing operation.
The use of these artificially obliqued faces
can be disabled using the 'font-synthesis' property.
Note: While oblique faces can be simulated by artificially sloping the glyphs of the regular face,
this is not equivalent to a true oblique,
in which optical stroke thicknesses are properly preserved despite the slant.
It is always better to use an actual oblique font rather than rely on a synthetic version.
For the purposes of font matching,
User agents may treat ''italic'' as a synonym for ''oblique''.
For user agents that treat these values distinctly,
synthesis must not be performed for ''italic''.
Note: Authors should also be aware that synthesized approaches might not be suitable
for scripts like Cyrillic, where italic forms are very different in shape.
It is always better to use an actual italic font rather than rely on a synthetic version.
Note: Many scripts lack the tradition of mixing a cursive form within text rendered with a normal face.
Chinese, Japanese and Korean fonts almost always lack italic or oblique faces.
Fonts that support a mixture of scripts
will sometimes omit specific scripts, such as Arabic,
from the set of glyphs supported in the italic face.
User agents should be careful about making character map assumptions across faces
when implementing synthesis across fonts,
as italic faces in a family can have different character maps than Roman faces.
Name: font-size Value: <> | < > | < > | math Initial: medium Applies to: all elements and text Inherited: yes Percentages: refer to parent element's font size Computed value: an absolute length Animation type: by computed value type
[ xx-small | x-small | small | medium | large | x-large | xx-large | xxx-large ]
[ larger | smaller ]If the parent element has a keyword font size in the absolute size keyword mapping table, ''larger'' may compute the font size to the next entry in the table, and ''smaller'' may compute the font size to the previous entry in the table. For example, if the parent element has a font size of ''font-size:medium'', specifying a value of ''larger'' may make the font size of the child element ''font-size:large''. Instead of using next and previous items in the previous keyword table, User agents may instead use a simple ratio to increase or decrease the font size relative to the parent element. The specific ratio is unspecified, but should be around 1.2–1.5. This ratio may vary across different elements. Note: A sight-impaired user may request a user agent use a higher ratio than default, in order to aid readability. In addition, a user agent may choose to use different ratios when it detects paragraph text as opposed to title text.
p { font-size: 12pt; } blockquote { font-size: larger } em { font-size: 150% } em { font-size: 1.5em }
font-size: clamp(10px, ..., 36px);
CSS absolute-size values | xx-small | x-small | small | medium | large | x-large | xx-large | xxx-large |
---|---|---|---|---|---|---|---|---|
scaling factor | 3/5 | 3/4 | 8/9 | 1 | 6/5 | 3/2 | 2/1 | 3/1 |
HTML headings | h6 | h5 | h4 | h3 | h2 | h1 | ||
HTML <{font}> sizes | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
Name: font-size-adjust Value: none | <> Initial: none Applies to: all elements and text Inherited: yes Percentages: N/A Computed value: a number or the keyword ''font-size-adjust/none'' Animation type: by computed value type
p { font-family: Verdana, Futura, Times; } p.adj { font-size-adjust: 0.545; } <p>Lorem ipsum dolor sit amet, ...</p> <p class="adj">Lorem ipsum dolor sit amet, ...</p>Verdana has a relatively high aspect value of 0.545, meaning lowercase letters are relatively tall compared to uppercase letters, so at small sizes text appears legible. Times has a lower aspect value of 0.447, and so if fallback occurs, the text will be less legible at small sizes than Verdana unless font-size-adjust is also specified.
c = ( a / a' ) swhere:
s = font-size value a = aspect value as specified by the 'font-size-adjust' property a' = aspect value of actual font c = adjusted font-size to useNegative values are invalid. This value applies to any font that is selected but in typical usage it should be based on the aspect value of the first font in the font-family list. If this is specified accurately, the
(a/a')
term in the formula above
is effectively 1 for the first font
and no adjustment occurs.
If the value is specified inaccurately,
text rendered using the first font in the family list
will display differently in older user agents
that don't support 'font-size-adjust'.
ex
and ch
but does not affect the size of em
units.
Since numeric values of 'line-height'
refer to the computed size of 'font-size',
'font-size-adjust' does not affect the used value of 'line-height'.
Note: In CSS, authors often specify 'line-height'
as a multiple of the 'font-size'.
Since the 'font-size-adjust' property affects the used value of 'font-size',
authors should take care setting the line height
when 'font-size-adjust' is used.
Setting the line height too tightly can result in
overlapping lines of text in this situation.
p { font-family: Futura; font-size: 500px; } span { border: solid 1px red; } .adjust { font-size-adjust: 0.5; } <p><span>b</span><span class="adjust">b</span></p>The box on the right is a bit bigger than the one on the left, so the aspect value of this font is something less than 0.5. Adjust the value until the boxes align.
Name: font Value: [ [ <<'font-style'>> || <> || <<'font-weight'>> || < > ]? <<'font-size'>> [ / <<'line-height'>> ]? <<'font-family'>> ] | < > Initial: see individual properties Applies to: all elements and text Inherited: yes Percentages: see individual properties Computed value: see individual properties Animation type: see individual properties
<Values for the 'font-width!!property' property can also be included but only those supported in CSS Fonts level 3, none of the 'font-width!!property' values added in this specification can be used in the 'font' shorthand:> = [normal | small-caps]
<Therefore we have the following classification of font-related properties and their interaction with the 'font!!property' property:> = [normal | ultra-condensed | extra-condensed | condensed | semi-condensed | semi-expanded | expanded | extra-expanded | ultra-expanded]
These properties may be set using the 'font!!property' property:
These may not be set, but are reset to their initial values:
There are neither set nor reset by the 'font!!property' property:
p { font: 12pt/14pt sans-serif } p { font: 80% sans-serif } p { font: x-large/110% "new century schoolbook", serif } p { font: bold italic large Palatino, serif } p { font: normal small-caps 120%/120% fantasy } p { font: condensed oblique 12pt "Helvetica Neue", serif; } p { font: condensed oblique 25deg 753 12pt "Helvetica Neue", serif; }In the second rule, the font size percentage value ("80%") refers to the computed 'font-size' of the parent element. In the third rule, the line height percentage ("110%") refers to the font size of the element itself. The first three rules do not specify the 'font-variant!!property' and 'font-weight!!property' explicitly, so these properties receive their initial values (''font-variant/normal''). Notice that the font family name ''"new century schoolbook"'', which contains spaces, is enclosed in quotes. The fourth rule sets the 'font-weight!!property' to ''bold'', the 'font-style!!property' to ''italic'', and implicitly sets 'font-variant!!property' to ''font-variant/normal''. The fifth rule sets the 'font-variant!!property' (''small-caps''), the 'font-size!!property' (120% of the parent's font size), the 'line-height!!property' (120% of the font size) and the 'font-family!!property' (''fantasy''). It follows that the keyword
p { font: 80% sans-serif; /* for older user agents */ font: condensed 80% sans-serif; }System fonts can only be set as a whole; that is, the font family, size, weight, style, etc. are all set at the same time. These values can then be altered individually if desired. If no font with the indicated characteristics exists on a given platform, the user agent should either intelligently substitute (e.g., a smaller version of the ''caption'' font might be used for the ''small-caption'' font), or substitute a user agent default font. As for regular fonts, if, for a system font, any of the individual properties are not part of the operating system's available user preferences, those properties should be set to their initial values. That is why this property is "almost" a shorthand property: system fonts can only be specified with this property, not with 'font-family!!property' itself, so 'font!!property' allows authors to do more than the sum of its subproperties. However, the individual properties such as 'font-weight!!property' are still given values taken from the system font, which can be independently varied. Note that the keywords used for the system fonts listed above are only treated as keywords when they occur in the initial position, in other positions the same string is treated as part of the font family name:
font: menu; /* use the font settings for system menus */ font: large menu; /* use a font family named "menu" */
Name: font-synthesis-weight Value: auto | none Initial: auto Applies to: all elements and text Inherited: yes Percentages: N/A Computed value: specified keyword Media: visual Animation type: discrete
Name: font-synthesis-style Value: auto | none Initial: auto Applies to: all elements and text Inherited: yes Percentages: N/A Computed value: specified keyword Media: visual Animation type: discrete
In vertical text, for positive oblique angles, the glyph is skewed such that the line-over edge shifts towards the line-right side while the line-under edge shifts towards the line-left side. For negative oblique angles, the glyph is skewed such that the line-over edge shifts towards the line-left side while the line-under edge shifts towards the line-right side. Skewing is about the center of the glyph.
Name: font-synthesis-small-caps Value: auto | none Initial: auto Applies to: all elements and text Inherited: yes Percentages: N/A Computed value: specified keyword Animation type: discrete
Name: font-synthesis-position Value: auto | none Initial: auto Applies to: all elements and text Inherited: yes Percentages: N/A Computed value: specified keyword Animation type: discrete
Name: font-synthesis Value: none | [ weight || style || small-caps || position] Initial: weight style small-caps position Applies to: all elements and text Inherited: yes Percentages: N/A Computed value: specified keyword(s) Animation type: discrete
'font-synthesis' value | 'font-synthesis-weight' value | 'font-synthesis-style' value | 'font-synthesis-small-caps' value | 'font-synthesis-position' value |
---|---|---|---|---|
none | none | none | none | none |
weight | auto | none | none | none |
style | none | auto | none | none |
small-caps | none | none | auto | none |
position | none | none | none | auto |
weight style | auto | auto | none | none |
weight small-caps | auto | none | auto | none |
weight position | auto | none | none | auto |
style small-caps | none | auto | auto | none |
style position | none | auto | none | auto |
small-caps position | none | none | auto | auto |
weight style small-caps | auto | auto | auto | none |
weight style position | auto | auto | none | auto |
weight small-caps position | auto | none | auto | auto |
style small-caps position | none | auto | auto | auto |
weight style small-caps position | auto | auto | auto | auto |
*:lang(ar) { font-synthesis: none; }
Browser | Timeout | Fallback | Swap |
---|---|---|---|
Chrome 35+ | 3 seconds | yes | yes |
Opera | 3 seconds | yes | yes |
Firefox | 3 seconds | yes | yes |
Internet Explorer | 0 seconds | yes | yes |
Safari | 3 seconds | yes | yes |
@font-face { <> }
@font-face { font-family: Gentium; src: url(http://example.com/fonts/Gentium.woff); } p { font-family: Gentium, serif; }The user agent will download Gentium and use it when rendering text within paragraph elements. If for some reason the site serving the font is unavailable, the default serif font will be used.
Name: font-family Value: <This descriptor defines the font family name that will be used in all CSS font family name matching. It overrides the font family names contained in the underlying font data. If the font family name is the same as a font family available in a given user's environment, it effectively hides the underlying font for documents that use the stylesheet. This permits a web author to freely choose font-family names without worrying about conflicts with font family names present in a given user's environment. Likewise, platform substitutions for a given font family name must not be used.> For: @font-face Initial: N/A
Name: src Value: <This descriptor specifies the resource containing font data. Its value is a prioritized, comma-separated list of external references or locally-installed font face names. When a font is needed the user agent iterates over the set of references listed, using the first one it can successfully parse and activate. Parsing this descriptor is more complicated than parsing other descriptors; see [[#font-face-src-parsing]] for the parsing rules. Activation of a font involves downloading the file or reading it from disk, parsing it, and perhaps additional user-agent-dependent steps. Fonts containing invalid data or local font faces that are not found are ignored and the user agent loads the next font in the list.> For: @font-face Initial: N/A
<font-src> = <> [ format(< >)]? [ tech( < >#)]? | local(< >)
<font-format> = [<> | collection | embedded-opentype | opentype | svg | truetype | woff | woff2 ]
<font-tech> = [<> | < > | variations | palettes | incremental ]
<font-features-tech> = [features-opentype | features-aat | features-graphite]
<color-font-tech> = [color-COLRv0 | color-COLRv1 | color-SVG | color-sbix | color-CBDT ]
String form | Equivalent syntax |
---|---|
format("woff2") | format(woff2) |
format("woff") | format(woff) |
format("truetype") | format(truetype) |
format("opentype") | format(opentype) |
format("collection") | format(collection) |
format("woff2-variations") | format(woff2) tech(variations) |
format("woff-variations") | format(woff) tech(variations) |
format("truetype-variations") | format(truetype) tech(variations) |
format("opentype-variations") | format(opentype) tech(variations) |
@font-face { font-family: "MyIncrementallyLoadedWebFont"; src: url("FallbackURLForBrowsersWhichDontSupportIncrementalLoading.woff2") format("woff2"); src: url("MyIncrementallyLoadedWebFont.otf") format(opentype) tech(incremental); }
src: url(fonts/simple.woff); /* load simple.woff relative to stylesheet location */ src: url(/fonts/simple.woff); /* load simple.woff from absolute location */ src: url(fonts/coll.otc#foo); /* load font foo from collection coll.otc src: url(fonts/coll.woff2#foo); /* load font foo from woff2 collection coll.woff2 src: url(fonts.svg#simple); /* load SVG font with id 'simple' */
@font-face { font-family: bodytext; src: url(ideal-sans-serif.woff2) format("woff2"), url(ideal-sans-serif.woff) format("woff"), url(basic-sans-serif.ttf) format("opentype"); }
src: url(ideal.woff2) format("woff2"), url(unsupported.zeb) format("zebra"), url(basic.ttf) format("opentype");
@font-face { font-family: 源ノ角ゴシック Code JP; src: url(SourceHanCodeJP.otc#Regular) format("collection"), url(SourceHanCodeJP-Regular.ttf) format("opentype"); }
local()
can be used.
The locally-installed <local()
is a format-specific string
that uniquely identifies a single font face
within a larger family.
The name can optionally be enclosed in quotes.
If unquoted,
the unquoted font family name processing conventions apply;
in other words,
the name must be a sequence of identifiers
separated by whitespace
which is converted to a string
by joining the identifiers together
separated by a single space;
and thus,
CSS-wide keywords such as ''inherit'', and
<local()
.
/* regular face of Gentium */ @font-face { font-family: MyGentium; src: local(Gentium), /* prefer locally available Gentium */ url(Gentium.woff); /* otherwise, download it */ }
local()
would be an error:
@font-face { font-family: foo; src: local(inherit); }
/* bold face of Gentium */ @font-face { font-family: MyGentium; src: local(Gentium Bold), /* full font name */ local(Gentium-Bold), /* Postscript name */ url(GentiumBold.woff); /* otherwise, download it */ font-weight: bold; }Just as an ''@font-face'' rule specifies the characteristics of a single font within a family, the unique name used with
local()
specifies a single font,
not an entire font family.
Defined in terms of OpenType font data,
the Postscript name is found in
the font's
name table,
in the name record with nameID = 6
(see [[!OPENTYPE]] for more details).
The Postscript name is the commonly used key for all fonts on OSX
and for Postscript CFF fonts under Windows.
The full font name (nameID = 4) is used as a unique key
for fonts with TrueType glyphs on Windows.
For OpenType fonts with multiple localizations of the full font name,
the US English version must be used
(language ID = 0x409 for Windows and language ID = 0 for Macintosh)
or the first localization
when a US English full font name is not available
(the OpenType specification recommends that
all fonts
minimally include US English names).
User agents that also match other full font names,
e.g. matching the Dutch name when the current system locale is set to Dutch,
are considered non-conformant.
Note: This is done,
not to prefer English,
but to avoid matching inconsistencies
across font versions and OS localizations,
since font style names (e.g. "Bold")
are frequently localized into many languages
and the set of localizations available
varies widely across platform and font version.
User agents that match a concatenation of
family name (nameID = 1) with
style name (nameID = 2)
are considered non-conformant.
Note: This also allows for referencing faces
that belong to larger families
that cannot otherwise be referenced.
@font-face { font-family: Headline; src: local(Futura-Medium), url(images/fonts.svg#MyGeometricModern) format("svg"); }Create an alias for local Japanese fonts on different platforms:
@font-face { font-family: jpgothic; src: local(HiraKakuPro-W3), local(Meiryo), local(IPAPGothic); }Reference a font face that cannot be matched within a larger family:
@font-face { font-family: Hoefler Text Ornaments; /* has the same font properties as Hoefler Text Regular */ src: local(HoeflerText-Ornaments); }Since localized fullnames never match, a document with the header style rules below would always render using the default serif font, regardless whether a particular system locale parameter is set to Finnish or not:
@font-face { font-family: SectionHeader; src: local("Arial Lihavoitu"); /* Finnish fullname for Arial Bold, should fail */ font-weight: bold; } h2 { font-family: SectionHeader, serif; }A conformant user agent would never load the font 'gentium.eot' in the example below, since it is included in the first definition of the 'src!!descriptor' descriptor which is overridden by the second definition in the same ''@font-face'' rule:
@font-face { font-family: MainText; src: url(gentium.eot); /* for use with older user agents */ src: local("Gentium"), url(gentium.woff); /* Overrides src definition */ }
Name: font-style Value: auto | normal | italic | oblique [ <>{1,2} ]? For: @font-face Initial: auto
Name: font-weight Value: auto | <>{1,2} For: @font-face Initial: auto
Name: font-width Value: auto | <<'font-width'>>{1,2} For: @font-face Initial: auto
@font-face { font-family: BaskervilleSimple; src: url(baskerville-regular.woff2); }Unstyled text would display using the regular face defined in the ''@font-face'' rule: However, italic text would display in most user agents using synthetically obliqued glyphs from the regular face, since a separate italic face is not defined: Now consider a family for which an actual italic face is defined:
@font-face { font-family: BaskervilleFull; src: url(baskerville-regular.woff2); } @font-face { font-family: BaskervilleFull; src: url(baskerville-italic.woff2); font-style: italic; }The second ''@font-face'' rule defines the font resource
baskerville-italic.woff
to have style attributes of normal weight, normal stretch and italic style.
When displaying italic text,
the user agent will use this font,
since it's the closest match for italic text.
Thus, the text will display using glyphs designed by a type designer
rather than using synthetically obliqued glyphs from the regular face:
See the section on font matching
for more complete details of the process used
to select a particular face within a font family.
@font-face { font-family: Lastima; src: url(lastima-varfont.woff2); font-weight: 100 399; }The above ''@font-face'' rule indicates that
lastima-varfont.woff
should be used when
'font-weight!!property' is between 100 and 399. Depending on if there are any other ''@font-face'' rules which specify
font-family: Lastima
, lastima-varfont.woff
might be used for values of 'font-weight!!property'
outside of the 100 - 399 range. For more details, see the [[#font-matching-algorithm]].
As above, multiple ''@font-face'' rules may be joined together into a single
family, spanning multiple ranges of 'font-weight!!property', 'font-width!!property', and/or 'font-style!!property':
@font-face { font-family: Lastima; src: url(lastima-varfont-lightrange.woff2); font-weight: 100 399; } @font-face { font-family: Lastima; src: url(lastima-varfont-heavyrange.woff2); font-weight: 400 700; }The above ''@font-face'' rules indicate that
lastima-varfont-lightrange.woff
should be used when
'font-weight!!property' is between 100 and 399, whereas lastima-varfont-heavyrange.woff should be used when
'font-weight!!property' is between 400 and 700.
Name: unicode-range Value: <># Initial: U+0-10FFFF For: @font-face
UNICODE-RANGE
token made up of a "U+" or "u+" prefix
followed by a codepoint range in one of the three forms listed below.
Ranges that do not fit one of these forms are invalid
and cause the declaration to be ignored.
UNICODE-RANGE
token accepts six.
Within the comma-delimited list of Unicode ranges in a
'unicode-range!!descriptor' descriptor declaration, ranges may overlap. The union
of these ranges defines the set of codepoints for which the
corresponding font may be used. User agents must not download or use
the font for codepoints outside this set. User agents may normalize
the list of ranges into a list that is different but represents the
same set of codepoints.
The associated font might not contain glyphs for the entire set of
codepoints defined by the 'unicode-range!!descriptor' descriptor. When the font
is used, the effective character map is the intersection of the
codepoints defined by 'unicode-range!!descriptor' with the font's character map.
This allows authors to define supported ranges in terms of broad
ranges without worrying about the precise codepoint ranges supported
by the underlying font.
@font-face { font-family: BBCBengali; src: url(fonts/BBCBengali.woff) format("woff"); unicode-range: U+00-FF, U+980-9FF; }
@font-face { font-family: STIXGeneral; src: local(STIXGeneral), url(/stixfonts/STIXGeneral.otf); unicode-range: U+000-49F, U+2000-27FF, U+2900-2BFF, U+1D400-1D7FF; }
@font-face { font-family: JapaneseWithGentium; src: local(MSMincho); /* no range specified, defaults to entire range */ } @font-face { font-family: JapaneseWithGentium; src: url(../fonts/Gentium.woff); unicode-range: U+0-2FF; }
/* fallback font - size: 4.5MB */ @font-face { font-family: DroidSans; src: url(DroidSansFallback.woff); /* no range specified, defaults to entire range */ } /* Japanese glyphs - size: 1.2MB */ @font-face { font-family: DroidSans; src: url(DroidSansJapanese.woff); unicode-range: U+3000-9FFF, U+ff??; } /* Latin, Greek, Cyrillic along with some punctuation and symbols - size: 190KB */ @font-face { font-family: DroidSans; src: url(DroidSans.woff); unicode-range: U+000-5FF, U+1e00-1fff, U+2000-2300; }For simple Latin text, only the font for Latin characters is downloaded:
body { font-family: DroidSans; } <p>This is that</p>In this case the user agent first checks the unicode-range for the font containing Latin characters (DroidSans.woff). Since all the characters above are in the range U+0-5FF, the user agent downloads the font and renders the text with that font. Next, consider text that makes use of an arrow character (⇨):
<p>This ⇨ that<p>The user agent again first checks the unicode-range of the font containing Latin characters. Since U+2000-2300 includes the arrow code point (U+21E8), the user agent downloads the font. For this character however the Latin font does not have a matching glyph, so the effective unicode-range used for font matching excludes this code point. Next, the user agent evaluates the Japanese font. The unicode-range for the Japanese font, U+3000-9FFF and U+ff??, does not include U+21E8, so the user agent does not download the Japanese font. Next the fallback font is considered. The ''@font-face'' rule for the fallback font does not define unicode-range so its value defaults to the range of all Unicode code points. The fallback font is downloaded and used to render the arrow character.
Name: font-feature-settings Value: normal | <># Initial: normal For: @font-face
Name: font-variation-settings Value: normal | [ <> < >]# Initial: normal For: @font-face
Name: font-named-instance Value: auto | <If the 'font-named-instance!!descriptor' descriptor is set to a value other than ''font-named-instance/auto'', then the appropriate stage in the [[#font-feature-variation-resolution]] will inspect the font file to find the first named instance in the font which has a localized name equal to the given <> Initial: auto For: @font-face
@font-face { font-family: "AccuroVar"; src: url("accurovar.otf") format("opentype"); font-named-instance: "Grotesque"; font-variation-settings: "XHGT" 0.7; }
@font-face { font-family: GeometricModern; src: url(font.woff); } p { /* font will be downloaded for pages with p elements */ font-family: GeometricModern, sans-serif; } h2 { /* font may be downloaded for pages with h2 elements, even if Futura is available locally */ font-family: Futura, GeometricModern, sans-serif; }In cases where textual content is loaded before downloadable fonts are available, user agents must render text according to the '@font-face/font-display' descriptor of that ''@font-face'' block. In cases where the font download fails, user agents must display the text visibly. Authors are advised to use fallback fonts in their font lists that closely match the metrics of the downloadable fonts to avoid large page reflows where possible.
Access-Control-Allow-Origin
HTTP header. For other schemes, no explicit mechanism to allow
cross-origin loading, beyond what is permitted by the
fetch
algorithm, is defined or required.
https://example.com/page.html
and all URLs link to valid
font resources supported by the user agent.
Fonts defined with the 'src!!descriptor' descriptor values below will be loaded:
/* same origin (i.e. domain, scheme, port match document) */ src: url(fonts/simple.woff); /* data urls with no redirects are treated as same origin */ src: url("data:application/font-woff;base64,..."); /* cross origin, different domain */ /* Access-Control-Allow-Origin response header set to '*' */ src: url(http://another.example.com/fonts/simple.woff);Fonts defined with the 'src!!descriptor' descriptor values below will fail to load:
/* cross origin, different scheme */ /* no Access-Control-xxx headers in response */ src: url(http://example.com/fonts/simple.woff); /* cross origin, different domain */ /* no Access-Control-xxx headers in response */ src: url(http://another.example.com/fonts/simple.woff);
Name: font-display Value: auto | block | swap | fallback | optional Initial: auto For: @font-face
Name: font-display Value: auto | block | swap | fallback | optional Initial: auto For: @font-feature-values
Name: font-language-override Value: normal | <This descriptor defines initial settings that apply when the font defined by an @font-face rule is rendered. It does not affect font selection. Values are identical to those defined for the 'font-language-override!!property' property defined below except that the value inherit is omitted. When multiple font feature descriptors, properties, or variations are used, the cumulative effect on text rendering is detailed in the section [[#font-feature-variation-resolution]] below.> For: @font-face Initial: normal
Name: ascent-override Value: normal | <> For: @font-face Initial: normal
Name: descent-override Value: normal | <> For: @font-face Initial: normal
Name: line-gap-override Value: normal | <> For: @font-face Initial: normal
@font-face { font-family: overridden-font; ascent-override: 50%; ... } <span style="font-family: overridden-font; font-size: 20px;"> Outer span content <span style="font-size: 150%;">Inner span content</span> </span>The outer span uses an ascent value of 10px, whereas the inner span uses 15px.
@font-face { font-family: cool-web-font; src: url("https://example.com/font.woff"); } @font-face { font-family: fallback-to-local; src: local(Some Local Font); /* Override metric values to match cool-web-font */ ascent-override: 125%; descent-override: 25%; line-gap-override: 0%; } <div style="font-family: cool-web-font, fallback-to-local">Title goes here</div> <img src="https://example.com/largeimage" alt="A large image that you don't want to shift">The image will not be vertically shifted when the user agent finishes loading and switches to use the web font.
Name: font-kerning Value: auto | normal | none Initial: auto Applies to: all elements and text Inherited: yes Percentages: n/a Computed value: as specified Animation type: discrete
Kerning is the contextual adjustment of inter-glyph spacing. This property controls metric kerning, kerning that utilizes adjustment data contained in the font.
For fonts that do not include kerning data this property will have no visible effect. When rendering with OpenType fonts, the [[!OPENTYPE]] specification suggests that kerning be enabled by default. When kerning is enabled, the relevant OpenType kerning features are enabled (for horizontal [=typographic modes=] and for [=sideways typesetting=] in vertical [=typographic modes=], the kern feature; for [=upright typesetting=] in [=vertical typographic modes=], the vkrn feature. User agents must also support fonts that only support kerning via data contained in a kern font table, as detailed in the OpenType specification. If the 'letter-spacing' property is defined, kerning adjustments are considered part of the default spacing and letter spacing adjustments are made after kerning has been applied.
When set to 'auto', user agents can determine whether to apply kerning or not based on a number of factors: text size, script, or other factors that influence text processing speed. Authors who want proper kerning should use 'normal' to explicitly enable kerning. Likewise, some authors may prefer to disable kerning in situations where performance is more important than precise appearance. However, in well-designed modern implementations the use of kerning generally does not have a large impact on text rendering speed.
Name: font-variant-ligatures Value: normal | none | [ <common-lig-values> || <discretionary-lig-values> || <historical-lig-values> || <contextual-alt-values> ] Initial: normal Applies to: all elements and text Inherited: yes Percentages: n/a Computed value: as specified Animation type: discrete
Ligatures and contextual forms are ways of combining glyphs to produce more harmonized forms.
<common-lig-values> = [ common-ligatures | no-common-ligatures ]
<discretionary-lig-values> = [ discretionary-ligatures | no-discretionary-ligatures ]
<historical-lig-values> = [ historical-ligatures | no-historical-ligatures ]
<contextual-alt-values> = [ contextual | no-contextual ]
Individual values have the following meanings:
Required ligatures, needed for correctly rendering complex scripts, are not affected by the settings above, including ''none'' (OpenType feature: rlig).
Name: font-variant-position Value: normal | sub | super Initial: normal Applies to: all elements and text Inherited: yes Percentages: n/a Computed value: as specified Animation type: discrete
This property is used to enable typographic subscript and superscript glyphs. These are alternate glyphs designed within the same em-box as default glyphs and are intended to be laid out on the same baseline as the default glyphs, with no resizing or repositioning of the baseline. They are explicitly designed to match the surrounding text and to be more readable without affecting the line height.
Individual values have the following meanings:
Because of the semantic nature of subscripts and superscripts, when the value is either 'sub' or 'super' for a given contiguous run of text, if a variant glyph is not available for all the characters in the run, simulated glyphs should be synthesized for all characters using reduced forms of the glyphs that would be used without this feature applied. This is done per run to avoid a mixture of variant glyphs and synthesized ones that would not align correctly. In the case of OpenType fonts that lack subscript or superscript glyphs for a given character, user agents must synthesize appropriate subscript and superscript glyphs.
In situations where text decorations are only applied to runs of text containing superscript or subscript glyphs, the synthesized glyphs may be used, to avoid problems with the placement of decorations.
In the past,
user agents have used font-size
and vertical-align
to simulate subscripts and superscripts
for the
sub
and sup
elements.
To allow a backwards compatible way
of defining subscripts and superscripts,
it is recommended
that authors use conditional rules [[CSS3-CONDITIONAL]]
so that older user agents will still render
subscripts and superscripts via
the older mechanism.
Because font-size: smaller
is often used for these elements,
the effective scaling factor
applied to subscript and superscript text
varies depending upon the size.
For larger text,
the font size is often reduced by a third
but for smaller text sizes,
the reduction can be much less.
This allows subscripts and superscripts
to remain readable
even within elements using small text sizes.
User agents should consider this
when deciding how to synthesize
subscript and superscript glyphs.
The OpenType font format defines subscript and superscript metrics in the OS/2 table [[!OPENTYPE]] but these are not always accurate in practice and so cannot be relied upon when synthesizing subscript and superscript glyphs.
Authors should note that fonts typically only provide subscript and superscript glyphs for a subset of all characters supported by the font. For example, while subscript and superscript glyphs are often available for Latin numbers, glyphs for punctuation and letter characters are less frequently provided. The synthetic fallback rules defined for this property try to ensure that subscripts and superscripts will always appear but the appearance may not match author expectations if the font used does not provide the appropriate alternate glyph for all characters contained in a subscript or superscript.
This property is not cumulative. Applying it to elements within a subscript or superscript won't nest the placement of a subscript or superscript glyph. Images contained within text runs where the value of this property is 'sub' or 'super' will be drawn just as they would if the value was 'normal'.
Because of these limitations, 'font-variant-position' is not recommended for use in user agent stylesheets. Authors should use it in cases where subscripts or superscripts will only contain the narrow range of characters supported by the fonts specified.
The variant glyphs use the same baseline as the default glyphs would use. There is no shift in the placement along the baseline, so the use of variant glyphs doesn't affect the height of the inline box or alter the height of the linebox. This makes superscript and subscript variants ideal for situations where it's important that leading remain constant, such as in multi-column layout.
A typical user agent default style for the sub element:
sub { vertical-align: sub; font-size: smaller; line-height: normal; }
Using 'font-variant-position' to specify typographic subscripts in a way that will still show subscripts in older user agents:
@supports ( font-variant-position: sub ) { sub { vertical-align: baseline; font-size: 100%; line-height: inherit; font-variant-position: sub; } }
User agents that support the 'font-variant-position' property will select a subscript variant glyph and render this without adjusting the baseline or font-size. Older user agents will ignore the 'font-variant-position' property definition and use the standard defaults for subscripts.
Name: font-variant-caps Value: normal | small-caps | all-small-caps | petite-caps | all-petite-caps | unicase | titling-caps Initial: normal Applies to: all elements and text Inherited: yes Percentages: n/a Computed value: as specified Animation type: discrete
This property allows the selection of alternate glyphs used for small or petite capitals or for titling. These glyphs are specifically designed to blend well with the surrounding normal glyphs, to maintain the weight and readability which suffers when text is simply resized to fit this purpose.
Individual values have the following meanings:
The availability of these glyphs is based on whether a given feature is defined or not in the feature list of the font. User agents can optionally decide this on a per-script basis but should explicitly not decide this on a per-character basis.
Some fonts may only support a subset or none of the features described for this property. For backwards compatibility with CSS 2.1, if 'small-caps' or 'all-small-caps' is specified but small-caps glyphs are not available for a given font, user agents should simulate a small-caps font, for example by taking a normal font and replacing the glyphs for lowercase letters with scaled versions of the glyphs for uppercase characters (replacing the glyphs for both upper and lowercase letters in the case of 'all-small-caps').
The 'font-feature-settings' property also affects the decision of whether or not to use a simulated small-caps font (unlike CSS Fonts 3).
#example1 { font-variant-caps: small-caps; } #example2 { font-variant-caps: small-caps; font-feature-settings: 'smcp' 0; }For fonts which don't support small caps, both #example1 and #example2 should be rendered with synthesized small caps. However, for fonts which do support small caps, #example1 should be rendered with native small caps, while #example2 should be rendered without any small-caps (native or synthesized).
To match the surrounding text, a font may provide alternate glyphs for caseless characters when these features are enabled but when a user agent simulates small capitals, it must not attempt to simulate alternates for codepoints which are considered caseless.
If either 'petite-caps' or 'all-petite-caps' is specified for a font that doesn't support these features, the property behaves as if 'small-caps' or 'all-small-caps', respectively, had been specified. If 'unicase' is specified for a font that doesn't support that feature, the property behaves as if 'small-caps' was applied only to lowercased uppercase letters. If 'titling-caps' is specified with a font that does not support this feature, this property has no visible effect. When simulated small capital glyphs are used, for scripts that lack uppercase and lowercase letters, 'small-caps', 'all-small-caps', 'petite-caps', 'all-petite-caps' and 'unicase' have no visible effect.
When casing transforms are used to simulate small capitals, the casing transformations must match those used for the 'text-transform' property.
As a last resort, unscaled uppercase letter glyphs in a normal font may replace glyphs in a small-caps font so that the text appears in all uppercase letters.
Quotes rendered italicized, with small-caps on the first line:
blockquote { font-style: italic; } blockquote:first-line { font-variant: small-caps; } <blockquote>I'll be honor-bound to slap them like a haddock.</blockquote>
Name: font-variant-numeric Value: normal | [ <> || < > || < > || ordinal || slashed-zero ] Initial: normal Applies to: all elements and text Inherited: yes Percentages: n/a Computed value: as specified Animation type: discrete
Specifies control over numerical forms. The example below shows how some of these values can be combined to influence the rendering of tabular data with fonts that support these features. Within normal paragraph text, proportional numbers are used while tabular numbers are used so that columns of numbers line up properly:
Possible combinations:
<numeric-figure-values> = [ lining-nums | oldstyle-nums ]
<numeric-spacing-values> = [ proportional-nums | tabular-nums ]
<numeric-fraction-values> = [ diagonal-fractions | stacked-fractions ]
Individual values have the following meanings:
In the case of 'ordinal', although ordinal forms are often the same as superscript forms, they are marked up differently.
For superscripts, the variant property is only applied to the sub-element containing the superscript:
sup { font-variant-position: super; } x<sup>2</sup>
For ordinals, the variant property is applied to the entire ordinal number rather than just to the suffix (or to the containing paragraph):
.ordinal { font-variant-numeric: ordinal; } <span class="ordinal">17th</span>
In this case only the "th" will appear in ordinal form, the digits will remain unchanged. Depending upon the typographic traditions used in a given language, ordinal forms may differ from superscript forms. In Italian, for example, ordinal forms sometimes include an underline in the ordinal design.
A simple flank steak marinade recipe, rendered with automatic fractions and old-style numerals:
.amount { font-variant-numeric: oldstyle-nums diagonal-fractions; } <h4>Steak marinade:</h4> <ul> <li><span class="amount">2</span> tbsp olive oil</li> <li><span class="amount">1</span> tbsp lemon juice</li> <li><span class="amount">1</span> tbsp soy sauce</li> <li><span class="amount">1 1/2</span> tbsp dry minced onion</li> <li><span class="amount">2 1/2</span> tsp italian seasoning</li> <li>Salt & pepper</li> </ul> <p>Mix the meat with the marinade and let it sit covered in the refrigerator for a few hours or overnight.</p>
Note that the fraction feature is only applied to values not the entire paragraph. Fonts often implement this feature using contextual rules based on the use of the slash ('/') character. As such, it's not suitable for use as a paragraph-level style.
Name: font-variant-alternates Value: normal | [ stylistic(<>) || historical-forms || styleset(< >#) || character-variant(< >#) || swash(< >) || ornaments(< >) || annotation(< >) ] Initial: normal Applies to: all elements and text Inherited: yes Percentages: n/a Computed value: as specified Animation type: discrete
<feature-value-name> = <For any given character, fonts can provide a variety of alternate glyphs in addition to the default glyph for that character. This property provides control over the selection of these alternate glyphs. For many of the property values listed below, several different alternate glyphs are available. How many alternates are available and what they represent is font-specific, so these are each marked font specific in the value definitions below. Because the nature of these alternates is font-specific, the ''@font-feature-values'' rule is used to define values for a specific font family or set of families that associate a font-specific numeric <>
@font-feature-values Noble Script { @swash { swishy: 1; flowing: 2; } } p { font-family: Noble Script; font-variant-alternates: swash(flowing); /* use swash alternate #2 */ }When a particular <
/* these two style rules are effectively the same */ p { font-variant-alternates: swash(unknown-value); } /* not a defined value, ignored */ p { font-variant-alternates: normal; }This allows values to be defined and used for a given set of font families but ignored if fallback occurs, since the font family name would be different. If a given value is outside the range supported by a given font, the value is ignored. These values never apply to generic font families. Individual values have the following meanings:
swsh 1
feature on one font face might turn on the swash version of capital Q,
while on another font face it turns on the swash version of the &.
Thus, specifying the index in 'font-feature-settings'
requires that the author know exactly which font will be used on an element;
if they get it wrong (due to font fallback selecting a different font)
they might end up turning on an entirely different,
and undesirable,
feature to what they wanted!
It also means that the author can't easily turn on similar features for elements with different fonts;
they have to individually set different 'font-feature-settings' values for each
that uses the correct numeric indexes for the desired features.
To fix this issue,
the ''@font-feature-values'' rule lets an author assign,
for each font face,
a human-friendly name to specific feature indexes.
Using these friendly names,
an author can easily turn on similar features regardless of the font in use
(if they've defined that name for all the fonts),
and be sure they're not accidentally turning on unrelated features
(as fonts without those names defined for them simply won't do anything).
Using a commonly named value allows authors to use a single style rule to cover a set of fonts for which the underlying selector is different for each font. If either font in the example below is found, a circled number glyph will be used:
@font-feature-values Otaru Kisa { @annotation { circled: 1; black-boxed: 3; } } @font-feature-values Taisho Gothic { @annotation { boxed: 1; circled: 4; } } h3.title { /* circled form defined for both fonts */ font-family: Otaru Kisa, Taisho Gothic; font-variant: annotation(circled); }Trying to turn on the "circled" forms for either font explicitly, using 'font-feature-values', would require the author know for certain which font will be used; if they expected "Otaru Kisa" and wrote ''font-feature-values: nalt 1;'', it would turn on "circled" characters in Otara Kisa, but would instead turn on boxed characters if the system fell back to Taisho Gothic, as that's what Taisho Gothic associates with
nalt 1
!
@font-feature-values = @font-feature-values <># { < > } font-feature-value-type = <<@stylistic>> | <<@historical-forms>> | <<@styleset>> | <<@character-variant>> | <<@swash>> | <<@ornaments>> | <<@annotation>> @stylistic = @stylistic { < > } @historical-forms = @historical-forms { < > } @styleset = @styleset { < > } @character-variant = @character-variant { < > } @swash = @swash { < > } @ornaments = @ornaments { < > } @annotation = @annotation { < > }
/* Default */ @font-feature-values foo { @swash { pretty: 1; cool: 2; } } /* Repeated declaration names */ @font-feature-values foo { @swash { pretty: 0; pretty: 1; cool: 2; } } /* Multiple blocks of the same type */ @font-feature-values foo { @swash { pretty: 1; } @swash { cool: 2; } } /* Multiple rules for the same family */ @font-feature-values foo { @swash { pretty: 1; } } @font-feature-values foo { @swash { cool: 2; } }
@font-feature-values Bongo { @swash { ornate: 1; } annotation { boxed: 4; } /* should be @annotation! */ @swash { double-loops: 1; flowing: -1; } /* negative value */ @ornaments ; /* incomplete definition */ @styleset { double-W: 14; sharp-terminals: 16 1 } /* missing ; */ redrum /* random editing mistake */ }The example above is equivalent to:
@font-feature-values Bongo { @swash { ornate: 1; } @swash { double-loops: 1; } @styleset { double-W: 14; sharp-terminals: 16 1; } }
@font-feature-values Mercury Serif { @styleset { stacked-g: 3; /* "two-storey" versions of g, a */ stacked-a: 4; } }page.css:
@font-feature-values Mercury Serif { @styleset { geometric-m: 7; /* alternate version of m */ } } body { font-family: Mercury Serif, serif; /* enable both the use of stacked g and alternate m */ font-variant-alternates: styleset(stacked-g, geometric-m); }
@font-feature-values Jupiter Serif { @swash { swishy: 5; /* implies ss05 = 1 */ swirly: 2; /* implies ss02 = 1 */ } }The ''character-variant()'' property value and the ''@character-variant'' descriptor allow two values, which enables a feature (from the first value) and sets it to a given (second) value.
@font-feature-values MM Greek { @character-variant { alpha-2: 1 2; } /* implies cv01 = 2 */ @character-variant { beta-3: 2 3; } /* implies cv02 = 3 */ }For the ''styleset()'' property value and ''@styleset'' rule, multiple values indicate the style sets to be enabled. Values between 1 and 99 enable OpenType features ss01 through ss99. However, the OpenType standard only officially defines ss01 through ss20. For OpenType fonts, values greater than 99 or equal to 0 do not generate a syntax error when parsed but enable no OpenType features.
@font-feature-values Mars Serif { @styleset { alt-g: 1; /* implies ss01 = 1 */ curly-quotes: 3; /* implies ss03 = 1 */ code: 4 5; /* implies ss04 = 1, ss05 = 1 */ } @styleset { dumb: 125; /* >99, ignored */ } @swash { swishy: 3 5; /* more than 1 value for swash, syntax error */ } } p.codeblock { /* implies ss03 = 1, ss04 = 1, ss05 = 1 */ font-variant-alternates: styleset(curly-quotes, code); }For <<@character-variant>>, a single value between 1 and 99 indicates the enabling of OpenType feature cv01 through cv99. For OpenType fonts, values greater than 99 or equal to 0 are ignored but do not generate a syntax error when parsed but enable no OpenType features. When two values are listed, the first value indicates the feature used and the second the value passed for that feature. If more than two values are assigned to a given name, a syntax error occurs and the entire feature value definition is ignored.
@font-feature-values MM Greek { @character-variant { alpha-2: 1 2; } /* implies cv01 = 2 */ @character-variant { beta-3: 2 3; } /* implies cv02 = 3 */ @character-variant { epsilon: 5 3 6; } /* more than 2 values, syntax error, definition ignored */ @character-variant { gamma: 12; } /* implies cv12 = 1 */ @character-variant { zeta: 20 3; } /* implies cv20 = 3 */ @character-variant { zeta-2: 20 2; } /* implies cv20 = 2 */ @character-variant { silly: 105; } /* >99, ignored */ @character-variant { dumb: 323 3; } /* >99, ignored */ } #title { /* use the third alternate beta, first alternate gamma */ font-variant-alternates: character-variant(beta-3, gamma); } p { /* zeta-2 follows zeta, implies cv20 = 2 */ font-variant-alternates: character-variant(zeta, zeta-2); } .special { /* zeta follows zeta-2, implies cv20 = 3 */ font-variant-alternates: character-variant(zeta-2, zeta); }
In the figure above, the text in red is rendered using a font containing character variants that mimic the character forms found on a Byzantine seal from the 8th century A.D. Two lines below is the same text displayed in a font without variants. Note the two variants for U and N used on the seal.
@font-feature-values Athena Ruby { @character-variant { leo-B: 2 1; leo-M: 13 3; leo-alt-N: 14 1; leo-N: 14 2; leo-T: 20 1; leo-U: 21 2; leo-alt-U: 21 4; } } p { font-variant: discretionary-ligatures character-variant(leo-B, leo-M, leo-N, leo-T, leo-U); } span.alt-N { font-variant-alternates: character-variant(leo-alt-N); } span.alt-U { font-variant-alternates: character-variant(leo-alt-U); } <p>ENO....UP͞RSTU<span class="alt-U">U</span>͞<span class="alt-U">U</span>ΚΑΙTỤẠG̣IUPNS</p> <p>LEON|ΚΑΙCONSTA|NTI<span class="alt-N">N</span>OS..|STOIBAṢ.|LIṢROM|AIO<span class="alt-N">N</span></p>
Name: font-variant-east-asian Value: normal | [ <> || < > || ruby ] Initial: normal Applies to: all elements and text Inherited: yes Percentages: n/a Computed value: as specified Animation type: discrete
Allows control of glyph substitution and sizing in East Asian text.
<east-asian-variant-values> = [ jis78 | jis83 | jis90 | jis04 | simplified | traditional ]
<east-asian-width-values> = [ full-width | proportional-width ]
Individual values have the following meanings:
The various JIS variants reflect the glyph forms defined in different Japanese national standards. Fonts generally include glyphs defined by the most recent national standard, but it's sometimes necessary to use older variants, to match signage for example.
The 'simplified' and 'traditional' values allow control over the glyph forms for characters which have been simplified over time but for which the older, traditional form is still used in some contexts. The exact set of characters and glyph forms will vary to some degree by the context for which a given font was designed.
Name: font-variant Value: normal | none | [ [ <> || < > || < > || < > ] || [ small-caps | all-small-caps | petite-caps | all-petite-caps | unicase | titling-caps ] || [ stylistic(< >) || historical-forms || styleset(< >#) || character-variant(< >#) || swash(< >) || ornaments(< >) || annotation(< >) ] || [ < > || < > || < > || ordinal || slashed-zero ] || [ < > || < > || ruby ] || [ sub | super ] || [ text | emoji | unicode ] ] Initial: normal Applies to: all elements and text Inherited: yes Percentages: n/a Computed value: as specified Animation type: discrete
The 'font-variant!!property' property is a shorthand for all font-variant subproperties: * 'font-variant-ligatures' * 'font-variant-position' * 'font-variant-caps' * 'font-variant-numeric' * 'font-variant-alternates' * 'font-variant-east-asian' * 'font-variant-emoji' The value 'normal' resets all subproperties of 'font-variant!!property' to their initial value. The ''none'' value sets 'font-variant-ligatures' to 'none' and resets all other font feature properties to their initial value. Like other shorthands, using 'font-variant' resets unspecified 'font-variant' subproperties to their initial values.
It does not reset the values of 'font-language-override', 'font-feature-settings!!property' or 'font-variation-settings!!property'.
Name: font-feature-settings Value: normal | <># Initial: normal Applies to: all elements and text Inherited: yes Percentages: n/a Computed value: as specified Animation type: discrete
This property provides low-level control over OpenType font features. It is intended as a way of providing access to font features that are not widely used but are needed for a particular use case.
If you want to set this font feature | then use this instead of 'font-feature-settings!!property' | Notes |
---|---|---|
Kerning (kern ) or Vertical Kerning (vkrn ) | 'font-kerning!!property': ''font-kerning/normal'' | The 'font-kerning!!property' property will set the kern or vkrn feature depending on the 'writing-mode'.
|
Standard Ligatures (liga ) or Contextual Ligatures (clig ) | 'font-variant-ligatures!!property': ''font-variant-ligatures/common-ligatures'' | |
Discretionary Ligatures (dlig ) | 'font-variant-ligatures!!property': ''font-variant-ligatures/discretionary-ligatures'' | |
Historical Ligatures (hlig ) | 'font-variant-ligatures!!property': ''font-variant-ligatures/historical-ligatures'' | |
Contextual Alternates (calt ) | 'font-variant-ligatures!!property': ''font-variant-ligatures/contextual'' | |
Subscript (subs ) | 'font-variant-position!!property': ''font-variant-position/sub'' | |
Superscript (sups ) | 'font-variant-position!!property': ''font-variant-position/super'' | |
Small Capitals (smcp ) | 'font-variant-caps!!property': ''font-variant-caps/small-caps'' | |
Small Capitals From Capitals (c2sc ) | 'font-variant-caps!!property': ''font-variant-caps/all-small-caps'' | |
Petite Capitals (pcap ) | 'font-variant-caps!!property': ''font-variant-caps/petite-caps'' | |
Petite Capitals From Capitals (c2pc ) | 'font-variant-caps!!property': ''font-variant-caps/all-petite-caps'' | |
Unicase (unic ) | 'font-variant-caps!!property': ''font-variant-caps/unicase'' | |
Titling (titl ) | 'font-variant-caps!!property': ''font-variant-caps/titling-caps'' | |
Lining Figures (lnum ) | 'font-variant-numeric!!property': ''font-variant-numeric/lining-nums'' | |
Oldstyle Figures (onum ) | 'font-variant-numeric!!property': ''font-variant-numeric/oldstyle-nums'' | |
Proportional Figures (pnum ) | 'font-variant-numeric!!property': ''font-variant-numeric/proportional-nums'' | |
Tabular Figures (tnum ) | 'font-variant-numeric!!property': ''font-variant-numeric/tabular-nums'' | |
Fractions (frac ) | 'font-variant-numeric!!property': ''font-variant-numeric/diagonal-fractions'' | |
Alternative Fractions (afrc ) | 'font-variant-numeric!!property': ''font-variant-numeric/stacked-fractions'' | |
Ordinals (ordn ) | 'font-variant-numeric!!property': ''font-variant-numeric/ordinal'' | |
Slashed Zero (zero ) | 'font-variant-numeric!!property': ''font-variant-numeric/slashed-zero'' | |
Historical Forms (hist ) | 'font-variant-alternates!!property': ''font-variant-alternates/historical-forms'' | |
Stylistic Alternates (salt ) | 'font-variant-alternates!!property': ''font-variant-alternates/stylistic()'' | Define which alternate gets used by making an ''@font-feature-values'' rule |
Character Variant 1 - Character Variant 99 (cv01 - cv99 ) | 'font-variant-alternates!!property': ''font-variant-alternates/character-variant()'' | Define which character variant gets used by making an ''@font-feature-values'' rule |
Swash (swsh ) or Contextual Swash (cswh ) | 'font-variant-alternates!!property': ''font-variant-alternates/swash()'' | Define which swash gets used by making an ''@font-feature-values'' rule |
Ornaments (ornm ) | 'font-variant-alternates!!property': ''font-variant-alternates/ornaments()'' | Define which ornament gets used by making an ''@font-feature-values'' rule |
Alternate Annotation Forms (nalt ) | 'font-variant-alternates!!property': ''font-variant-alternates/annotation()'' | Define which annotation gets used by making an ''@font-feature-values'' rule |
JIS78 Forms (jp78 ) | 'font-variant-east-asian!!property': ''font-variant-east-asian/jis78'' | |
JIS83 Forms (jp83 ) | 'font-variant-east-asian!!property': ''font-variant-east-asian/jis83'' | |
JIS90 Forms (jp90 ) | 'font-variant-east-asian!!property': ''font-variant-east-asian/jis90'' | |
JIS2004 Forms (jp04 ) | 'font-variant-east-asian!!property': ''font-variant-east-asian/jis04'' | |
Simplified Forms (smpl ) | 'font-variant-east-asian!!property': ''font-variant-east-asian/simplified'' | |
Traditional Forms (trad ) | 'font-variant-east-asian!!property': ''font-variant-east-asian/traditional'' | |
Full Widths (fwid ) | 'font-variant-east-asian!!property': ''font-variant-east-asian/full-width'' | |
Proportional Widths (pwid ) | 'font-variant-east-asian!!property': ''font-variant-east-asian/proportional-width'' | |
Ruby Notation Forms (ruby ) | 'font-variant-east-asian!!property': ''font-variant-east-asian/ruby'' |
For example, there is no font-variant value to control Scientific Inferiors (small numerals used in chemical formulae). Readability is enhanced by using them, so they must be enabled using font-feature-settings:
.chem { font-feature-settings: 'sinf' }
The entire property value is set at once. Unlike the font-variant properties, there is no way to modify the inherited value by adding or removing individual features.
A value of 'normal' means that no change in glyph selection or positioning occurs due to this property.
Feature tag values have the following syntax:
<feature-tag-value> = <opentype-tag> [ <integer [0,∞]> | on | off ]? <opentype-tag> = <string>
The < Feature tags
not present in the font are ignored;
a user agent must not attempt to synthesize fallback behavior
based on these feature tags.
The one exception is that
user agents may synthetically support the kern feature
with fonts that contain kerning data in the form of a 'kern' table
but lack kern feature support
in the 'GPOS' table. In general, authors should
use the 'font-kerning' property
to explicitly enable or disable kerning
since this property always affects fonts
with either type of kerning data. If present,
a value indicates an index used for glyph selection.
An <integer> value must be 0 or greater.
A value of 0 indicates that the feature is disabled.
For boolean features,
a value of 1 enables the feature.
For non-boolean features,
a value of 1 or greater enables the feature
and indicates the feature selection index. A
value of 'on' is synonymous with 1
and 'off' is synonymous with 0.
If the value is omitted, a value of 1 is assumed.
The computed value
of font-feature-settings is a map,
so any duplicates in the specified value
must not be preserved.
If the same feature tag appears more than once,
the value associated with the last appearance supersedes
any previous value for that axis. The computed value contains the de-duplicated feature tags,
sorted in ascending order by [=code unit=].
When values greater than the range
supported by the font
are specified,
the behavior is explicitly undefined.
For boolean features, in general these will enable the feature.
For non-boolean features,
out of range values will in general
be equivalent to a 0 value.
However,
in both cases the exact behavior
will depend upon the way the font is designed
(specifically, which type of lookup is used
to define the feature). Implementations may choose to ignore
turning off features which
the OpenType specification says are always required,
such as required ligatures "rlig". Although specifically defined for OpenType feature tags,
feature tags for other modern font formats
that support font features
may be added in the future.
Where possible,
features defined for other font formats
should attempt to follow
the pattern of registered OpenType tags. The Japanese text below will be rendered with half-width kana characters: The computed value contains the de-duplicated axis names,
sorted in ascending order by [=code unit=]. For background on these, see [[PFE-report]]. The The CSSFontFeatureValuesRule interface represents a
font-feature-settings: "sinf" 1; /* sinf=1 enable Scientific Inferiors */
font-feature-settings: "sinf" on; /* sinf=1 enable Scientific Inferiors */
font-feature-settings: 'sinf'; /* sinf=1 enable Scientific Inferiors */
font-feature-settings: "sinf" off; /* sinf=0 disable Scientific Inferiors */
font-feature-settings: "sinf", 'twid'; /* sinf=1, twid=1 enable Scientific Inferiors and Third Widths */
font-feature-settings: "sinf" "twid"; /* invalid, need a comma-delimited list */
font-feature-settings: "silly" off; /* invalid, tag too long */
font-feature-settings: "PKRN"; /* PKRN=1 enable custom feature */
font-feature-settings: sinf; /* invalid, tag must be a string */
body { font-feature-settings: "hwid"; /* Half-width OpenType feature */ }
<p>毎日カレー食べてるのに、飽きない</p>
Font language override: the 'font-language-override' property
Name: font-language-override
Value: normal | <
<!-- Display text using S'gaw Karen specific features -->
<p lang="ksw">...</p>
Unknown OpenType language system tags are silently ignored, and do not affect
glyph selection and placement.
Font Feature and Variation Resolution
As described in the previous section,
font features and variations can be enabled in a variety of ways,
either via the use of 'font-variant!!property',
'font-feature-settings!!property',
'font''font-variation-settings!!property' in a style rule
or within an ''@font-face'' rule.
The resolution order for the union of these settings is defined below.
Features defined via CSS properties are applied on top of layout engine default features.
Default features
For OpenType fonts,
user agents must enable the default features
defined in the OpenType documentation
for a given script and writing mode.
Required ligatures, common ligatures and contextual forms
must be enabled by default
(OpenType features: rlig, liga, clig, calt),
along with localized forms
(OpenType feature: locl),
and features required for proper display of composed characters and marks
(OpenType features: ccmp, mark, mkmk).
These features must always be enabled,
even when the value of the 'font-variant!!property' and 'font-feature-settings!!property' properties is
Feature and variation precedence
General and font specific font feature property settings are
resolved in the order below, in ascending order of precedence. This ordering is
used to construct a combined list of font features that affect a given
text run.
1. Font features enabled by default are applied, including features required for a given script.
See [[#default-features]] for a description of these.
2. Font variations as enabled by the 'font-weight!!property',
'font-width!!property', and 'font-style!!property' properties are applied.
The application of the value enabled by
'font-style!!property' is affected by font selection, because this property might select an
italic or an oblique font. The value applied is the closest matching value as determined
by the font matching algorithm. User agents must apply
at most one value due to the 'font-style!!property' property; both "ital" and "slnt" values must
not be set together.
If the selected font is defined in an ''@font-face'' rule, then the values applied at this step
should be clamped to the value of the 'font-weight!!descriptor', 'font-width!!descriptor',
and 'font-style!!descriptor'
descriptors in that ''@font-face'' rule.
Then, the values applied in this step should be clamped (possibly again) to the values
that are supported by the font.
3. The language specified by the inherited value of lang/xml:lang is applied.
4. If the font is defined via an ''@font-face'' rule, the font language override
implied by the 'font-language-override!!descriptor' descriptor in the ''@font-face'' rule is applied.
5. If the font is defined via an ''@font-face'' rule, that ''@font-face'' rule includes
at least one valid 'font-named-instance' descriptor
with a value other than 'font-named-instance/none',
and the loaded font resource includes a named instance with that name
according to the [[#localized-name-matching]] rules,
then all the variation values represented by that named instance are applied.
These values are clamped to the values that are supported by the font.
6. If the font is defined via an ''@font-face'' rule, the font variations
implied by the 'font-variation-settings!!descriptor' descriptor in the ''@font-face'' rule are applied.
7. If the font is defined via an ''@font-face'' rule, the font features
implied by the 'font-feature-settings!!descriptor' descriptor in the ''@font-face'' rule are applied.
8. The font language override implied by the value of the 'font-language-override!!property' property is applied.
9. Font variations implied by the value of the 'font-optical-sizing!!property' property are applied.
10. Font features implied by the value of the 'font-variant!!property' property,
the related 'font-variant!!property' subproperties and any other CSS property
that uses OpenType features (e.g. the 'font-kerning!!property' property) are applied.
11. Feature settings determined by properties other than 'font-variant!!property' or
'font-feature-settings!!property' are applied. For example, setting a
non-default value for the 'letter-spacing' property disables optional ligatures.
12. Font variations implied by the value of the 'font-variation-settings!!property' property are applied.
These values should be clamped to the values that are supported by the font.
13. Font features implied by the value of 'font-feature-settings!!property' property are applied.
Feature precedence examples
body {
font-variant-numeric: proportional-nums;
}
table.prices td {
font-variant-numeric: tabular-nums;
}
local()
in the 'src!!descriptor' descriptor of the ''@font-face'' definition:
@font-face {
font-family: BodyText;
src: local("HiraMaruPro-W4");
font-variant: proportional-width;
font-feature-settings: "ital"; /* Latin italics within CJK text feature */
}
body { font-family: BodyText, serif; }
If available, a Japanese font "Hiragino Maru Gothic" will be used. When text
rendering occurs, Japanese kana will be proportionally spaced and Latin text will
be italicized. Text rendered with the fallback serif font will use default
rendering properties.
@font-face {
font-family: main;
src: url(fonts/ffmeta.woff) format("woff");
font-variant: discretionary-ligatures;
}
body { font-family: main, Helvetica; }
span.special { font-variant-ligatures: no-discretionary-ligatures; }
Suppose one adds a rule using 'font-feature-settings' to enable discretionary ligatures:
body { font-family: main, Helvetica; }
span { font-feature-settings: "dlig"; }
span.special { font-variant-ligatures: no-discretionary-ligatures; }
In this case, discretionary ligatures will be rendered
within spans of class "special".
This is because both the 'font-feature-settings' and 'font-variant-ligatures' properties
apply to these spans.
Although the ''no-discretionary-ligatures'' setting of 'font-variant-ligatures'
effectively disables the OpenType "dlig" feature,
because the 'font-feature-settings' is resolved after that,
the "dlig" value reenables discretionary ligatures.
Font Variation Properties
Note: The technology in use in this section is named "font variations."
An instance of one such font as a "variable font."
Optical sizing control: the 'font-optical-sizing' property
Name: font-optical-sizing
Value: auto | none
Initial: auto
Applies to: all elements and text
Inherited: yes
Percentages: n/a
Computed value: specified keyword
Animation type: discrete
'font-size' must be considered when selecting a variation value for the "opsz" axis,
but other signals may also be considered.
Note: User agents are expected to supply a value for the "opsz" axis
which is close to the used value for 'font-size'.
However, user agents might wish to consider other factors
such as pixel density of the screen,
or the solid angle the text subtends in the viewer's retina.
Experiments have shown,
however, that disregarding these other ancillary factors
and using only 'font-size' might be the best way for a user agent to select this value.
Pixel density as well as visual size of the text
may influence the variation value chosen for 'font-optical-sizing'.
When either pixel density or visual size of the text
changes in response to a user operation or style change,
user agents must not choose a new value for this variation value
unless the change is layout-causing.
User agents are free to determine which changes are layout-causing.
Note: Some user operations,
such as pinch-zoom,
can be considered not-layout-causing
if they do not cause text to reflow.
However, other user operations,
such as increasing text size for accessibility purposes,
can be considered layout-causing because they cause text to reflow.
Similarly, the 'transform' property can be considered not-layout-causing
because transforms generally do not cause text to reflow.
Each user-agent is free to decide
whether or not each operation is layout-changing or not.
User agents must not synthesize optical sizing
when it is not performed by the font directly.
User agents must not select a value for the "opsz" axis
which is not supported by the font used for rendering the text.
This can be accomplished by clamping a chosen value to the range supported by the font.
'font-optical-sizing' interacts with 'font-size-adjust'. When applying optical sizing, User agents must
apply an optical sizing value appropriate for the adjusted font size, subject to the above restrictions.
Low-level font variation settings control: the 'font-variation-settings' property
Name: font-variation-settings
Value: normal | [ <
If you want to set this variation axis
then use this instead of 'font-variation-settings!!property'
Notes
Weight ( wght
)'font-weight!!property' The 'font-weight!!property' property will set the wght
axis if one is present.
Width ( wdth
)'font-width!!property' The 'font-width!!property' property will set the wdth
axis if one is present.
Slant ( slnt
) or Italic (ital
)'font-style!!property' The 'font-style!!property' property will set the slnt
or ital
axis, depending on its value.
Optical size ( opsz
)'font-optical-sizing!!property' The 'font-optical-sizing!!property' property will set the opsz
axis if one is present.
slnt
axis directly,
via 'font-variation-settings',
remember that it is defined
with a positive angle meaning a counter-clockwise slant,
the opposite direction to CSS.
If the same axis name appears more than once, the value associated with the last appearance supersedes any previous value for that axis. This deduplication is observable by accessing the computed value of this property.
Color Font Support
Color fonts allow for font files to describe,
not just the contours describing the edges of glyphs,
but also the colors present inside the glyphs.
For some uses, such as emoji,
having the colors fixed in the font is appropriate.
For others, there is a need to control the colors used from a stylesheet.
Controlling Color Font Palettes: The 'font-palette' property
Many color font file formats allow colors within glyphs to be parameterized.
In these fonts, colors are referenced by index when describing the geometry of each glyph.
These indices are resolved within a current active palette
using a lookup table present inside the font.
However, many fonts contain multiple palettes,
each containing a set of complementary colors
chosen by the font designer to provide pleasing visual results.
In addition, some color font file formats
provide a regular, uncolored glyph outline
as well as the colored versions.
Name: font-palette
Value: normal | light | dark | <
COLR
[[!OPENTYPE]] table, color index 0xFFFF should be rendered according the 'color' property.COLR
/CPAL
[[!OPENTYPE]] fonts, 'font-palette': ''font-palette/normal'' usually means rendering the font with the palette in the font at index 0.@media (prefers-color-scheme: dark) {
.banner {font-palette: dark;
}
}
@font-palette-values --pink {
font-family: Nabla;
base-palette: 1;
}
@font-palette-values --yellow {
font-family: Nabla;
base-palette: 7;
}
@keyframes animate-palette {
from {
font-palette: --yellow;
}
to {
font-palette: --pink;
}
}
p {
font-family: Nabla;
animation: animate-palette 1.4s infinite alternate linear;
}
User-defined font color palettes: The ''@font-palette-values'' rule
The @font-palette-values rule defines a color palette
and associates that color palette with a specific font.
This allows a web author to select arbitrary <
@font-palette-values <
@font-palette-values --Cooler {
font-family: Bixa;
base-palette: 1;
override-colors:
1 #7EB7E4;
}
@font-palette-values --Augusta {
font-family: Handover Sans;
base-palette: 3;
override-colors:
1 rgb(43, 12, 9),
3 var(--highlight);
}
@font-face {
font-family: Bixxxa;
src: url('./bixxxa.woff') format('woff');
}
@font-face {
font-family: Bungeehee;
src: url('./bungeehee.woff') format('woff');
}
@font-palette-values --ToxicGreen {
font-family: Bixxxa;
base-palette: 3; /* This is Bixxxa's green palette */
}
@font-palette-values --ToxicGreen {
font-family: Bungeehee;
base-palette: 7; /* This is Bungeehee's green palette... */
override-colors: 2 lime; /* ...except this is pink, which I overwrite to lime */
}
h1 {
font-family: Bixxxa;
font-palette: --ToxicGreen;
}
h2 {
font-family: Bungeehee;
font-palette: --ToxicGreen;
}
Example by Roel Nieskens
h3 {
font-family: Bixxxa, Bungeehee;
font-palette: --ToxicGreen;
}
Which would correctly apply the desired palette
in each font
even though they have different palette numbers.
Font family: the '@font-palette-values/font-family' descriptor
Name: font-family
Value: <
This descriptor defines the font families that this palette applies to,
using the same list of font families as [[#font-matching-algorithm]].
This palette will only ever be applied to the fonts with these family names.
The value of this descriptor means that only named font families are allowed
and rules that include generic fonts in the list of font families
are syntax errors.
If syntax errors occur within the font family list,
the descriptor must be ignored
(will still be in the CSS OM, but will not match any font families).
Specifying the base palette: the 'base-palette!!descriptor' descriptor
Name: base-palette
Value: light | dark | <
@font-palette-values --Festival {
font-family: Banner Flag;
base-palette: 1;
override-colors:
0 rgb(123, 64, 27),
1 darkblue,
2 var(--highlight);
}
@font-palette-values --Augusta {
font-family: Handover Sans;
base-palette: 3;
}
Overriding a colors from a palette: The 'override-colors!!descriptor' descriptor
Name: override-colors
Value: [ <
This descriptor overrides colors
to the initial color palette represented by this ''@font-palette-values'' rule.
The specified <
@font-palette-values --Festival {
font-family: Blaka Ink;
base-palette: 0;
override-colors:
0 oklch(0.63 0.12 105.7),
1 color(display-p3 0.23 0.22 0.04),
2 color(prophoto-rgb 0.37 0.27 0.09);
}
Selecting the text presentation style: The 'font-variant-emoji' property
Name: font-variant-emoji
Value: normal | text | emoji | unicode
Initial: normal
Applies to: all elements and text
Inherited: yes
Percentages: N/a
Computed value: specified keyword
Animation type: discrete
-u-
extension to the language tag accepted by lang
or xml:lang
should not be
considered when the user-agent decides whether to use emoji presentation or text presentation for a particular character.
@font-face {
font-family: "Custom Emoji";
src: url("CustomEmoji.ttf") format("truetype");
}
...
<div style="font-family: 'Custom Emoji'; font-variant-emoji: emoji;">🛋</div>
Font Taxonomy
A given font may belong in one or more of the following categories:
Installed Fonts
A font may be installed globally on a device. Such fonts are generally accessible in any application, even applications which have no concept of CSS. The file or files backing the font object exist on the user's device, not as a remote resource.
Installed Fonts must not be Web Fonts, and Web Fonts must not be Installed Fonts.
Web Fonts
A font may be backed by a remote resource, which must be requested using the user agent's resource fetching infrastructure. Web Fonts are represented by one of two mechanisms:
- ''@font-face'' rules
- A ''FontFace'' member of the Document's ''FontFaceSet''
A Web Font must not be accessible in any other Document from the one which either is associated with the ''@font-face'' rule or owns the ''FontFaceSet''. Other applications on the device must not be able to access Web Fonts.
Installed Fonts must not be Web Fonts, and Web Fonts must not be Installed Fonts.
Web Fonts shadow Installed Fonts, so if an Installed Font has the same family name as a Web Font, the Installed Font is not accessible.
Preinstalled Fonts and User-Installed Fonts
Users can choose to install fonts on their devices.
User-Installed Fonts are installed by an explicit action by the user,
such as clicking an "Install" button
or copying a file into a particular directory on their device.
Such fonts are User-Installed Fonts and also are Installed Fonts.
Web content authors should not count on the presence of user-installed fonts,
because there is no guarantee any user will have
performed the action to install a specific font.
Please see the Font Matching Algorithm
description of how user-installed fonts may interact with the font matching algorithm.
Any Installed Font which is not a User-Installed font is a Preinstalled Font. It is likely that all users of a particular version of a particular Operating System will have the same set of Preinstalled Fonts installed. As such, Web content authors targeting these Operating Systems may wish to use these fonts' family names inside 'font-family!!property' properties.
System Font
The System Font is the font which is used by the ''system-ui'' generic font family name. It is an example of a Preinstalled Font.
Font Technologies and Formats
Font tech
The 'features-opentype', 'features-aat' and 'features-graphite' techs
refer to support for font features,
commonly implemented in [[!OPENTYPE]] with the
GSUB
and the
GPOS
tables,
as well as in [[!AAT-FEATURES]] using the
morx
and
kerx
tables
and [[!GRAPHITE]] with the
Silf
,
Glat
,
Gloc
,
Feat
and
Sill
tables
as documented in the
Graphite Table Format.
The section on [[#font-rend-props]] describes properties that interact with these facilities.
The 'variations' tech refers to the support of font variations,
commonly implemented in [[!OPENTYPE]] with the
avar
,
cvar
,
fvar
,
gvar
,
HVAR
,
MVAR
,
STAT
, and
VVAR
tables,
as well as in [[!AAT-FEATURES]] using the
avar
,
cvar
,
fvar
,
gvar
tables.
The section on [[#basic-font-props]] as well as the section on [[#font-variation-props]]
describe properties that interact with these facilities.
The 'color-colrv0', 'color-colrv1', 'color-svg', 'color-sbix' and 'color-cbdt'
technologies refers to various types of color font file technologies.
Each one represents a table
(COLR
,
SVG
,
sbix
or
CBDT
)
inside [[!OPENTYPE]] or [[!AAT-FEATURES]] fonts which must be supported
to satisfy this requirement.
The 'palettes' tech refers to support for font palettes,
commonly implemented in the [[!OPENTYPE]] and [[!AAT-FEATURES]]
with the
CPAL
table.
The section on [[#color-font-support]] describes properties that interact with these facilities.
The 'incremental' tech
refers to client support for incremental font transfer [[IFT]].
@font-face {
font-family: "Trickster";
src: url("trickster-COLRv1.otf") format(opentype) tech(color-COLRv1),
url("trickster-outline.otf") format(opentype);
}
Font formats
Format strings defined by this specification are as follows.
The <
String
Font Format
Common extensions
Common media types
"collection"
OpenType Collection
.otc,.ttc
font/collection
"embedded-opentype"
Embedded OpenType
.eot
application/vnd.ms-fontobject
"opentype"
OpenType
.ttf, .otf
font/otf,
font/ttf
"svg"
SVG Font (deprecated)
.svg, .svgz
image/svg+xml
"truetype"
TrueType
.ttf
font/ttf
"woff"
WOFF 1.0 (Web Open Font Format)
.woff
font/woff
"woff2"
WOFF 2.0 (Web Open Font Format)
.woff2
font/woff2
Object Model
The contents of ''@font-face'' and ''@font-feature-values'' rules
can be accessed via the following extensions to the CSS Object Model.
The
The CSSFontFaceRule interface represents a <<@font-face>> rule.
CSSFontFaceRule
interface
[Exposed=Window]
interface CSSFontFaceDescriptors : CSSStyleDeclaration {
attribute [LegacyNullToEmptyString] CSSOMString src;
attribute [LegacyNullToEmptyString] CSSOMString fontFamily;
attribute [LegacyNullToEmptyString] CSSOMString font-family;
attribute [LegacyNullToEmptyString] CSSOMString fontStyle;
attribute [LegacyNullToEmptyString] CSSOMString font-style;
attribute [LegacyNullToEmptyString] CSSOMString fontWeight;
attribute [LegacyNullToEmptyString] CSSOMString font-weight;
attribute [LegacyNullToEmptyString] CSSOMString fontStretch;
attribute [LegacyNullToEmptyString] CSSOMString font-stretch;
attribute [LegacyNullToEmptyString] CSSOMString fontWidth;
attribute [LegacyNullToEmptyString] CSSOMString font-width;
attribute [LegacyNullToEmptyString] CSSOMString unicodeRange;
attribute [LegacyNullToEmptyString] CSSOMString unicode-range;
attribute [LegacyNullToEmptyString] CSSOMString fontFeatureSettings;
attribute [LegacyNullToEmptyString] CSSOMString font-feature-settings;
attribute [LegacyNullToEmptyString] CSSOMString fontVariationSettings;
attribute [LegacyNullToEmptyString] CSSOMString font-variation-settings;
attribute [LegacyNullToEmptyString] CSSOMString fontNamedInstance;
attribute [LegacyNullToEmptyString] CSSOMString font-named-instance;
attribute [LegacyNullToEmptyString] CSSOMString fontDisplay;
attribute [LegacyNullToEmptyString] CSSOMString font-display;
attribute [LegacyNullToEmptyString] CSSOMString fontLanguageOverride;
attribute [LegacyNullToEmptyString] CSSOMString font-language-override;
attribute [LegacyNullToEmptyString] CSSOMString ascentOverride;
attribute [LegacyNullToEmptyString] CSSOMString ascent-override;
attribute [LegacyNullToEmptyString] CSSOMString descentOverride;
attribute [LegacyNullToEmptyString] CSSOMString descent-override;
attribute [LegacyNullToEmptyString] CSSOMString lineGapOverride;
attribute [LegacyNullToEmptyString] CSSOMString line-gap-override;
};
[Exposed=Window]
interface CSSFontFaceRule : CSSRule {
readonly attribute CSSFontFaceDescriptors style;
};
The
CSSFontFeatureValuesRule
interfaceCSSRule
interface is extended as follows:partial interface CSSRule {
const unsigned short FONT_FEATURE_VALUES_RULE = 14;
};
@font-feature-values
rule.
[Exposed=Window]
interface CSSFontFeatureValuesRule : CSSRule {
attribute CSSOMString fontFamily;
readonly attribute CSSFontFeatureValuesMap annotation;
readonly attribute CSSFontFeatureValuesMap ornaments;
readonly attribute CSSFontFeatureValuesMap stylistic;
readonly attribute CSSFontFeatureValuesMap swash;
readonly attribute CSSFontFeatureValuesMap characterVariant;
readonly attribute CSSFontFeatureValuesMap styleset;
readonly attribute CSSFontFeatureValuesMap historicalForms;
};
[Exposed=Window]
interface CSSFontFeatureValuesMap {
maplike<CSSOMString, sequence<unsigned long>>;
undefined set(CSSOMString featureValueName,
(unsigned long or sequence<unsigned long>) values);
};
Each value map attribute of CSSOMString
CSSFontFeatureValuesMap
, readonly
CSSFontFeatureValuesRule
reflects the values
defined via a corresponding feature value block.
Thus, the annotation attribute
contains the values contained within a @annotation
feature value block, the
ornaments attribute contains the
values contained with a @ornaments
feature value block and so forth.
The CSSFontFeatureValuesMap
interface uses the
default map class methods
but the set
method has different behavior. It takes a sequence of unsigned integers and
associates it with a given featureValueName
. The method
behaves the same as the default map class method
except that a single unsigned long value is treated as a sequence of a
single value. The method throws an exception if an invalid number of
values is passed in. If the associated
feature value block
only allows a limited number of values, the set
method
throws an InvalidAccessError
exception when the input
sequence to set
contains more than the limited number of
values. See the
description of multi-valued feature value definitions
for details on the maximum number of values allowed for a given type
of feature value block. The get
method always returns a sequence of values, even if the sequence only contains
a single value.
The
CSSFontPaletteValuesRule
interface[Exposed=Window]
interface CSSFontPaletteValuesRule : CSSRule {
readonly attribute CSSOMString name;
readonly attribute CSSOMString fontFamily;
readonly attribute CSSOMString basePalette;
readonly attribute CSSOMString overrideColors;
};
The fontFamily
and basePalette
interfaces are parsed according to the appropriate CSS property syntax.
Serializing
Serializing font-related properties
Unless specifically noted for individual properties,
the properties defined in this module
follow the principles of
[[cssom#serializing-css-values]].
Serializing font-related at-rules
Unless specifically noted
for individual descriptors,
the descriptors defined for at-rules in this module
follow the principles of
[[cssom#serializing-css-values]].
In particular,
following the principle of shorter representation:
for descriptors which accept a range of values,
if the start and end values are the same
(the range is zero)
the descriptor is serialized as a single value, not a range.
@font-face {
font-family: "foo";
font-weight: 200 200;
}
would serialize as
@font-face {
font-family: "foo";
font-weight: 200;
}
/* Repeated declaration names, and multiple blocks of the same type*/
@font-feature-values foo {
@swash { pretty: 0; cool: 2; }
@swash { pretty: 1; }
}
would be serialized as:
/* Canonical serialization */
@font-feature-values foo {
@swash { cool: 2; pretty: 1; }
}
Appendix A: Mapping platform font properties to CSS properties
This appendix is included as background for some of the problems and
situations that are described in other sections. It should be viewed as
informative only.
Font properties in CSS are designed to be
independent of the underlying font formats used;
they can be used to specify bitmap fonts,
Type1 fonts,
SVG fonts
in addition to the common TrueType and OpenType fonts.
But there are facets of the TrueType and OpenType formats
that often cause confusion for authors
and present challenges to implementers
on different platforms.
Originally developed at Apple,
TrueType [[TRUETYPE]] was designed as an outline font format
for both screen and print.
Microsoft joined Apple
in developing the TrueType format
and both platforms have supported
TrueType fonts since then.
Font data in the TrueType format consists of
a set of tables distinguished with common four-letter tag names,
each containing a specific type of data.
For example,
naming information,
including copyright and license information,
is stored in the 'name' table.
The character map ('cmap') table
contains a mapping
of character encodings to glyphs.
Apple later added additional tables
for supporting enhanced typographic functionality;
these are now called Apple Advanced Typography, or AAT, fonts.
Microsoft and Adobe developed
a separate set of tables for advanced typography
and called their format OpenType [[OPENTYPE]].
The OpenType specification is standardized at ISO as the
Open Font Format [[OPEN-FONT-FORMAT]].
In many cases the font data used under Microsoft Windows
or Linux
is slightly different from the data used under Apple's Mac OS X
because the TrueType format allowed for
explicit variation across platforms.
This includes font metrics,
names and
character map data.
Specifically,
font family name data is handled differently
across platforms.
For TrueType and OpenType fonts
these names are contained in the 'name' table,
in name records with name ID 1.
Multiple names can be stored for different locales,
but Microsoft recommends fonts
always include at least a US English version of the name.
On Windows,
Microsoft made the decision for backwards compatibility
to limit this family name to a maximum of four faces;
for larger groupings the
"preferred family" (name ID 16) or
"WWS family" (name ID 21)
can be used.
Other platforms such as OSX don't have this limitation,
so the family name is used to define all possible groupings.
Other name table data provides names used
to uniquely identify a specific face within a family.
The full font name (name ID 4) and
the Postscript name (name ID 6)
describe a single face uniquely.
For example,
the bold face of the Gill Sans family
has a fullname of "Gill Sans Bold" and
a Postscript name of "GillSans-Bold".
There can be multiple localized versions of the fullname for a given face,
but the Postscript name is always a unique name
made from a limited set of ASCII characters.
On various platforms,
different names are used to search for a font.
For example,
with the Windows GDI CreateIndirectFont API,
either a family or fullname can be used to lookup a face,
while on Mac OS X the CTFontCreateWithName API call is used
to lookup a given face
using the fullname and Postscript name.
Under Linux,
the fontconfig API allows
fonts to be searched using any of these names.
In situations where platform API's
automatically substitute other font choices,
it may be necessary to
verify a returned font matches a given name.
The weight of a given face can be determined
via the usWeightClass field of the OS/2 table
or inferred from the style name (name ID 2).
Likewise, the width can be determined
via the usWidthClass of the OS/2 table
or inferred from the style name.
For historical reasons
related to synthetic bolding at weights 200 or lower with the Windows GDI API,
font designers have sometimes skewed values in the OS/2 table
to avoid these weights.
Rendering complex scripts that use contextual shaping
such as Thai,
Arabic
and Devanagari
requires features present only in OpenType or AAT fonts.
Currently,
complex script rendering is supported
on Windows and Linux using OpenType font features
while both OpenType and AAT font features are used
under Mac OS X.
Security Considerations
See items 9, 16 and 17 in the self-review questionnaire below.
Privacy Considerations
Following Self-Review Questionnaire: Security and Privacy,
and using the [[#font-taxonomy]]:
What information might this feature expose to Web sites or other parties, and for what purposes is that exposure necessary?
This specification allows the use of Web Fonts,
which are requested on demand
but are not installed.
In the case where the document or stylesheet has a different origin to the Web Font,
this network request exposes information in the Referer header,
which may be harvested by font providers.
In addition to Web Fonts, this specification continues to allow
the use of Installed Fonts (both Preinstalled Fonts and User-Installed Fonts)
as introduced in CSS1.
While Web Fonts have the advantage of consistency across platforms,
Installed Fonts have the advantage of zero download time.
In some cases, and particularly for poorly-supported or minority languages,
Installed Fonts allow information to be displayed which could not otherwise be displayed
because there is no freely licensable Web Font which supports that language
or because the latency or download time would make it's use infeasible,
particularly for languages with a large character repertoire,
or on slow or metered connections.
Note: The set of installed fonts
available in the Font Matching Algorithm
is explicitly undefined.
The available set of fonts is
used by trackers to fingerprint users and reduce their privacy.
However, some installed fonts,
even some user-installed fonts,
are required to make languages readable.
User Agents may choose to make all installed fonts available
for language support and design integrity reasons,
or may choose to make some fonts unavailable for privacy reasons.
In addition, User Agents may have additional facilities for fine-tuning this balance,
such as interfaces which prompt users to explicitly make
certain requested fonts available or unavailable
(perhaps on a per-site basis).
Different User Agents, even running on the same Operating System,
are expected to strike different balances here.
In the case of user agents which perform rendering of local resources
(such as an HTML and CSS to PDF renderer,
or a Web-based wordprocessor)
access to all Installed Fonts
(both Preinstalled Fonts and User-Installed Fonts)
is necessary to provide the expected functionality.
An attacker may obtain fingerprinting information by querying the Installed Fonts.
In contrast to older technologies
(notably Adobe Flash, which provided a complete list of Installed Fonts
and sent this information in HTTP headers)
such probing must be done one font at a time,
providing the font family name
and then checking
(either via script,
or by using unicode-range to selectively download webfonts
depending on whether the user has a font by a certain name
that supports a certain character)
whether the font was loaded.
This takes time, and checking for more than a few hundred fonts
introduces a noticeable delay in page rendering.
For especially privacy-sensitive contexts,
options would include never downloading any webfonts
(at the risk that some characters may be rendered incorrectly, or not at all),
or always downloading all webfonts whether needed or not
(ignoring unicode-range,
and potentially downloading vast quantities of unused fonts
each time the page is viewed).
Is this specification exposing the minimum amount of information necessary to power the feature?
An emerging consensus is that a user agent must expose Preinstalled Fonts
for correct functioning,
but there is no consensus on exposing User-Installed Fonts.
This specification allows a user agent
to ignore User-Installed Fonts for the purpose of the Font Matching Algorithm.
Several existing user agents already do this.
The minimum amount varies by type of user and is currently being debated.
There is a useful taxonomy of User-Installed Font users
which has been slightly extended.
A permissive amount of information exposes potentially more fingerprinting information;
a restrictive amount of information reduces fingerprinting but also reduces functionality
and in some cases, for minority languages, would break the Web completely for those users.
The possibility of a configurable, per-user opt-in to exposing some or all User-Installed Fonts,
or a per-origin opt-in, is being discussed.
The possibility of a privacy budget, which would penalize or disable
a malicious web page which tested a large number of fonts,
but allow a harmless page which tested a much smaller number,
has also been discussed.
Some user agents expose a more restricted set of Preinstalled Fonts
in their Private Browsing, Incognito, or Resist Fingerprinting modes,
compared to their normal mode.
How does this specification deal with personal information or personally-identifiable information or information derived thereof?
Personal information is not exposed by this specification.
Personally identifiable information may be exposed in some cases.
For example, for someone in Japan, having conditionally-enabled Japanese fonts
enumerable probably isn't a substantial fingerprinting vector.
For someone in Europe who has a Japanese IME in the text input menu, they are.
How does this specification deal with sensitive information?
Fingerprinting on Installed Fonts may expose sensitive information in some cases.
For example, persecuted minorities risk leaking sensitive information
by exposing that they use fonts required for a persecuted minority language;
either by requesting a Web Font from a third party service,
or exposing Preinstalled Fonts or User-Installed Fonts associated with that language.
Does this specification introduce new state for an origin that persists across browsing sessions?
No.
Specifically, Web Fonts must not be accessible
in any other Document from the one which either is associated with the @font-face rule
or owns the FontFaceSet.
Other applications on the device must not be able to access Web Fonts.
This avoids information leaking across origins.
Similarly, font palette values
must only be available to the documents that reference it.
Using an author-defined color palette outside of the documents that reference it
would constitute a security leak since the contents of one page
would be able to affect other pages,
something an attacker could use as an attack vector.
What information from the underlying platform, e.g. configuration data, is exposed by this specification to an origin?
The ''system-ui'' keyword exposes the operating system's default system UI font to fingerprinting mechanisms.
Does this specification allow an origin access to sensors on a user’s device
No.
What data does this specification expose to an origin? Please also document what data is identical to data exposed by other features, in the same or different contexts.
For third-party Web Fonts loaded via a stylesheet,
the stylesheet origin may be exposed to the third party in the Referer header.
In addition, careful pairing of unicode-range and distinct src urls
allows the third-party to see which characters are used on a page,
which is a privacy risk for large character repertoire scripts
such as CJK.
For third-party Web Fonts preloaded in the HTML,
the document origin may be similarly exposed.
Does this specification enable new script execution/loading mechanisms?
No.
Specifically, for SVG-in-OpenType color fonts,
the SVG used for glyph definitions should not contain script elements,
and any script elements that do occur will not be executed.
Does this specification allow an origin to access other devices?
No.
Does this specification allow an origin some measure of control over a user agent’s native UI?
There is some risk that an attacker can spoof a native UI feature
by determining the Operating System
and using native-looking fonts appropriate to that Operating System.
What temporary identifiers might this specification create or expose to the web?
None.
How does this specification distinguish between behavior in first-party and third-party contexts?
For font loads, user agents must use the
potentially CORS-enabled fetch method defined by the [[!HTML]] specification
for URLs defined within @font-face rules.
When fetching, user agents must use "Anonymous" mode,
set the referrer source to the stylesheet’s URL
and set the origin to the URL of the containing document.
Thus, fonts will typically not be loaded cross-origin
unless authors specifically take steps to permit cross-origin loads.
How does this specification work in the context of a user agent’s Private Browsing or "incognito" mode?
The specification makes no distinction.
Some user agents may expose a more restricted set of Installed Fonts in these modes.
Does this specification have a "Security Considerations" and "Privacy Considerations" section?
Yes.
Does this specification allow downgrading default security characteristics?
No.
What should this questionnaire have asked?
It should have asked whether a malicious payload could crash the application,
or indeed the entire Operating System,
or even cause remote code execution.
This possibility does exist for suitably crafted fonts
on some platforms
when fonts are installed and rendered,
and this has been exploited in the wild.
In practice, user agents running on Operating Systems with this vulnerability
use a font sanitizer to detect such malformed or malicious fonts
and prevent their being used.
Accessibility Considerations
The use of fonts to provide a visual rendering of text should not, in general, impact accessibility.
For example, people using a screen reader to render text to speech will not download fonts,
and are unaffected by what those fonts would have contained.
However, this assumes that the semantics conveyed by the font glyphs
and the semantics conveyed by the characters
are the same.
Historically, this has not always been the case.
For example, in the early days of the Web it was common to use fonts
(such as "Symbol", though others were used)
to make Latin letters have Greek glyphs;
while this worked visually,
it would not work with a screen reader
and text was also hard to search or index
because the mapping was font-specific.
With the rise of Unicode, it is now standard practice to use Greek characters for Greek text,
and for Greek glyphs in fonts to map to Greek characters.
Sadly, but avoidably, this practice persists
with badly designed icon fonts.
For example, such a font might put a "printer" icon on the Latin letter "P".
This practice scatters meaningless letters through the text,
which negatively affects text searching and indexing,
gives hard to understand rendering if the icon font does not load,
and impedes screen readers.
A well designed font must assign such icons to semantically meaningful characters.
For example, the printer icon might be assigned to the string "printer"
or to the Unicode character 🖨 U+1F5A8 (PRINTER).
Acknowledgments
The CSS Working group would like to thank:
Peter Constable for assorted language fixes.
Optical sizing image prepared by Nick Sherman.
Urdu samples prepared by Richard Ishida.
Munira Tursunova and Dominik Röttsches developed the features for animating font-palette.
John Hudson was kind enough to take the time to explain the subtleties of OpenType language tags
and provided the example of character variant usage for displaying text on Byzantine seals.
Elika Etemad supplied some of the initial design ideas for the '@font-feature-values' rule.
Special thanks to Tab Atkins Jr.
for providing the text for the section on Font Rendering Controls
as well as the section on the 'font-display!!descriptor' descriptor.
Special thanks to Ilya Grigorik and David Kuettel for their help in developing these sections.
Changes
Changes from the 21 December 2021 Working Draft
Changes from the 29 July 2021 Working Draft
Changes from the 17 November 2020 Working Draft
Changes from the 13 November 2019
Working Draft
Changes from the 20 September 2018
Working Draft
Changes from the 10 April 2018
Working Draft
Changes from the 20 September 2018
CSS Fonts 3 Recommendation
This summarizes the changes in CSS Fonts 4, compared to CSS Fonts 3.