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/2021/WD-css-fonts-4-20211221/ Editor: John Daggett, Invited Expert, https://twitter.com/nattokirai, w3cid 41498 Editor: Myles C. Maxfield, 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: font-palette,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-4; 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: 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">
<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-stretch
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.
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>
Name: font Value: [ [ <<'font-style'>> || <> || <<'font-weight'>> || < > ]? <<'font-size'>> [ / <<'line-height'>> ]? <<'font-family'>> ] | caption | icon | menu | message-box | small-caption | status-bar 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-stretch!!property' property can also be included but only those supported in CSS Fonts level 3, none of the 'font-stretch!!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;
}
The following values refer to system fonts:
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
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 Value: none | [ weight || style || small-caps] Initial: weight style small-caps 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 |
|---|---|---|---|
| none | none | none | none |
| weight | auto | none | none |
| style | none | auto | none |
| small-caps | none | none | auto |
| weight style | auto | auto | none |
| weight small-caps | auto | none | auto |
| style small-caps | none | auto | auto |
| weight style small-caps | 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 is required for the ''@font-face'' rule to be valid. 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: see prose For: @font-face Initial: N/AThis descriptor specifies the resource containing font data. It is required for the ''@font-face'' rule to be valid. 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.
<> [ format(< >)]? [ tech( < >#)]? | local(< >)
<font-format> = [<> | collection | embedded-opentype | opentype | svg | truetype | woff | woff2 ]
<font-tech> = [<> | < > | variations | palettes | incremental-patch | incremental-range | incremental-auto ]
<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-range);
}
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;
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.
/* regular face of Gentium */
@font-face {
font-family: MyGentium;
src: local(Gentium), /* prefer locally available Gentium */
url(Gentium.woff); /* otherwise, download it */
}
For OpenType and TrueType fonts,
this string is used to match only the Postscript name
or the full font name
in the name table of locally available fonts.
Which type of name is used varies by platform
and font,
so authors should include both of these names
to assure proper matching across platforms.
Platform substitutions for a given font name must not be used.
/* 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-stretch
Value: auto | <<'font-stretch'>>{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:


@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:

@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-stretch!!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-display!!descriptor' 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.

Subscript glyphs (top) vs. typical synthesized subscripts (bottom)
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.

Superscript alternate glyph (left), synthesized superscript glyphs (middle), and incorrect mixture of the two (right)
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').

Synthetic vs. real 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.

Caseless characters with small-caps, all-small-caps enabled
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.

Using small capitals to improve readability in acronym-laden text
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:

Using number styles
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 <># { < > } < > = < > { < > } < > = @stylistic | @historical-forms | @styleset | @character-variant | @swash | @ornaments | @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 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);
}

Byzantine seal text displayed with character variants
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> = <string> [ <integer> | on | off ]?
The <string> is a case-sensitive OpenType feature tag. As specified in the OpenType specification [[!OPENTYPE]], feature tags contain four ASCII characters. Tag strings longer or shorter than four characters, or containing characters outside the U+20–7E codepoint range are invalid. Feature tags need only match a feature tag defined in the font, so they are not limited to explicitly registered OpenType features. Fonts defining custom feature tags should follow the tag name rules defined in the OpenType specification [[!OPENTYPE-FEATURES]].
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=].
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 */
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:
body { font-feature-settings: "hwid"; /* Half-width OpenType feature */ }
<p>毎日カレー食べてるのに、飽きない</p>
Name: font-language-override Value: normal | <> Initial: normal Applies to: all elements and text Inherited: yes Percentages: N/A Computed value: specified string or the keyword ''font-language-override/none'' Animation type: discrete
<!-- Display text using S'gaw Karen specific features --> <p lang="ksw">...</p>
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.
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
Name: font-variation-settings Value: normal | [ <> < >]# Initial: normal Applies to: all elements and text Inherited: yes Percentages: n/a Computed value: the keyword ''font-variation-settings/normal'' or a list, each item a string paired with a number Animation type: (see prose)
| 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-stretch!!property' | The 'font-stretch!!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.
The computed value contains the de-duplicated axis names, sorted in ascending order by [=code unit=].
Although specifically defined for OpenType / TrueType variations, variation axes for other modern font formats that support font variations might be added in the future. Where possible, variations defined for other font formats should attempt to follow the pattern of registered variation axes. Animating font-variation-settings is possible using the following mechanism. Two declarations of font-feature-settings can be animated between if they are "like". "Like" declarations are ones where the same set of properties appear (in any order). Because successive duplicate properties are applied instead of prior duplicate properties, two declarations can be "like" even if they have differing number of properties. If two declarations are "like" then animation occurs pairwise between corresponding values in the declarations. Otherwise, animation is not possible. In this situation, the "from" values of the animation are swapped to the "to" values at an unspecified time during the animation.
Name: font-palette Value: normal | light | dark | <> Initial: normal Applies to: all elements and text Inherited: yes Percentages: N/a Computed value: specified keyword or identifier Animation type: discrete
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 <> {
<>
}
@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.
Name: font-family
Value: <>#
For: @font-palette-values
Initial: N/A
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).
Name: base-palette
Value: light | dark | <>
For: @font-palette-values
Initial: N/A
@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;
}
Name: override-colors
Value: [ <> <> ]#
For: @font-palette-values
Initial: N/A
This descriptor overrides colors
to the initial color palette represented by this ''@font-palette-values'' rule.
The '@font-palette-values/override-colors' descriptor takes
a comma-separated list of palette index entries and colors.
Each item in the comma-separated list represents a tuple of
an entry into the palette and a color to replace it with.
For each key/value pair in the value of this descriptor,
the color with that key in the initial palette (i.e. by using the 'base-palette' descriptor)
is overwritten by the color specified in this descriptor's value.
A key that is outside the range of indices of the initial palette is ignored.
Palette index entries
in the ''@font-palette-values/override-colors'' descriptor
are a (zero-based) palette index entry.
Integer values are zero-indexed.
If the keys of multiple distinct key/value pairs identify the same color index (either by name or by integer),
the last key is used for the purposes of rendering. However, for serialization purposes, both
key/value pairs are present.
Note: This means that using 'font-palette' with the same value on two different elements
might result in different used palettes
because the value of variables inside the ''@font-palette-values'' rule
might apply differently in the context of those two elements.
Colors provided from CSS
(as overrides, or as new entries)
may use any supported colorspace.
Note: The colors specified in versions 0 and 1 of the CPAL table are in sRGB.
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>
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-patch', 'incremental-range' and 'incremental-auto' techs
refer to client support for incremental font transfer [[IFT]],
using the patch-subset, range-request, or
automatic negotiation
between these two methods.
For background on these, see [[PFE-report]].
Web authors can specify the 'tech' function inside an ''@font-face'' 'src!!descriptor' descriptor to indicate that support is required for correct rendering of a font. This mechanism can be used for gracefully falling back to an ancillary font when requested support is not present.
@font-face {
font-family: "Trickster";
src: url("trickster-COLRv1.otf") format(opentype) tech(color-COLRv1),
url("trickster-outline.otf") format(opentype);
}
| String | Font Format | Common extensions |
|---|---|---|
| "collection" | OpenType Collection | .otc,.ttc |
| "embedded-opentype" | Embedded OpenType | .eot |
| "opentype" | OpenType | .ttf, .otf |
| "svg" | SVG Font (deprecated) | .svg, .svgz |
| "truetype" | TrueType | .ttf |
| "woff" | WOFF 1.0 (Web Open Font Format) | .woff |
| "woff2" | WOFF 2.0 (Web Open Font Format) | .woff2 |
CSSFontFaceRule interface
[Exposed=Window]
interface CSSFontFaceRule : CSSRule {
readonly attribute CSSStyleDeclaration style;
};
CSSFontFeatureValuesRule interfaceThe CSSRule interface is extended as follows:
partial interface CSSRule {
const unsigned short FONT_FEATURE_VALUES_RULE = 14;
};
The CSSFontFeatureValuesRule interface represents a @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;
};
[Exposed=Window]
interface CSSFontFeatureValuesMap {
maplike<CSSOMString, sequence<unsigned long>>;
undefined set(CSSOMString featureValueName,
(unsigned long or sequence<unsigned long>) values);
};
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.
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.
@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; }
}