Skip to content

Commit 5f06f59

Browse files
committed
[css-fonts-4] Move font-feature-values to Level 4
1 parent b6c4ba8 commit 5f06f59

2 files changed

Lines changed: 334 additions & 11 deletions

File tree

css-fonts-4/Overview.bs

Lines changed: 334 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1949,11 +1949,11 @@ Font features and variations: the 'font-variant!!descriptor', 'font-feature-sett
19491949
<pre class='descdef'>
19501950
Name: font-variant
19511951
Value: normal | none | [ <<common-lig-values>> || <<discretionary-lig-values>> || <<historical-lig-values>> ||
1952-
<<contextual-alt-values>> || <var title="stylistic">stylistic(<<feature-value-name>>)</var> || <var>historical-forms</var> ||
1953-
<var>styleset(<<feature-value-name>> #)</var> ||
1954-
<var>character-variant(<<feature-value-name>> #)</var> ||
1955-
<var>swash(<<feature-value-name>>)</var> || <var>ornaments(<<feature-value-name>>)</var> ||
1956-
<var>annotation(<<feature-value-name>>)</var> ||
1952+
<<contextual-alt-values>> || <var title="stylistic">stylistic(<&lt;feature-value-name&gt;>)</var> || <var>historical-forms</var> ||
1953+
<var>styleset(<&lt;feature-value-name&gt;> #)</var> ||
1954+
<var>character-variant(<&lt;feature-value-name&gt;> #)</var> ||
1955+
<var>swash(<&lt;feature-value-name&gt;>)</var> || <var>ornaments(<&lt;feature-value-name&gt;>)</var> ||
1956+
<var>annotation(<&lt;feature-value-name&gt;>)</var> ||
19571957
[ <i>small-caps</i> | <i>all-small-caps</i> | <i>petite-caps</i> | <i>all-petite-caps</i> | <i>unicase</i> | <i>titling-caps</i> ] ||
19581958
<<numeric-figure-values>> || <<numeric-spacing-values>> || <<numeric-fraction-values>> || <i>ordinal</i> || <i>slashed-zero</i> ||
19591959
<<east-asian-variant-values>> || <<east-asian-width-values>> || <i>ruby</i> ||
@@ -2816,8 +2816,8 @@ and what they represent is font-specific, so these are each marked
28162816
of these alternates is font-specific, the
28172817
''@font-feature-values'' rule is used to define values for a
28182818
specific font family or set of families that associate a font-specific
2819-
numeric <feature-index> with a custom
2820-
<feature-value-name>, which is then used in this
2819+
numeric &lt;feature-index&gt; with a custom
2820+
&lt;feature-value-name&gt;, which is then used in this
28212821
property to select specific alternates:
28222822

28232823
<pre>@font-feature-values Noble Script { @swash { swishy: 1; flowing: 2; } }
@@ -2827,10 +2827,10 @@ p {
28272827
font-variant-alternates: swash(flowing); /* use swash alternate #2 */
28282828
}</pre>
28292829

2830-
When a particular <feature-value-name> has not
2830+
When a particular &lt;feature-value-name&gt; has not
28312831
been defined for a given family or for a particular feature type, the
28322832
computed value must be the same as if it had been defined. However,
2833-
property values that contain these undefined <feature-value-name>
2833+
property values that contain these undefined &lt;feature-value-name&gt;
28342834
identifiers must be ignored when choosing glyphs.
28352835

28362836
<pre>/* these two style rules are effectively the same */
@@ -2896,7 +2896,330 @@ Individual values have the following meanings:
28962896
<h3 id="font-feature-values">
28972897
Defining font specific alternates: the ''@font-feature-values'' rule</h3>
28982898

2899-
Issue: Moved to Level 4; port the text for this from Fonts 3 .src to Fonts 4 .bs
2899+
Several of the possible values of 'font-variant-alternates' listed
2900+
above are labeled as <em>font specific</em>. For these features fonts may define
2901+
not just a single glyph but a set of alternate glyphs with an index to
2902+
select a given alternate. Since these are font family specific, the
2903+
''@font-feature-values'' rule is used to define named values for these indices
2904+
for a given family.
2905+
2906+
<div class="example">
2907+
<p>In the case of the swash Q in the example shown above, the swash could
2908+
be specified using these style rules:
2909+
</p>
2910+
2911+
<pre>
2912+
2913+
@font-feature-values Jupiter Sans {
2914+
@swash {
2915+
delicate: 1;
2916+
flowing: 2;
2917+
}
2918+
}
2919+
2920+
h2 { font-family: Jupiter Sans, sans-serif; }
2921+
2922+
/* show the second swash variant in h2 headings */
2923+
h2:first-letter { font-variant-alternates: swash(flowing); }
2924+
2925+
&lt;h2>Quick&lt;/h2></pre>
2926+
2927+
<p>When Jupiter Sans is present, the second alternate swash alternate will
2928+
be displayed. When not present, no swash character will be shown, since the
2929+
specific named value "flowing" is only defined for the Jupiter Sans family.
2930+
The @-mark indicates the name of the property value for which a named value
2931+
can be used. The name "flowing" is chosen by the author. The index that
2932+
represents each alternate is defined within a given font's data.</p>
2933+
</div>
2934+
2935+
<h4 id="font-feature-values-syntax">Basic syntax</h4>
2936+
2937+
An ''@font-feature-values'' rule is composed of a list of
2938+
font families followed by a block containing individual
2939+
''feature value blocks'' that take the
2940+
form of @-rules. Each block defines a set of named values for a specific font feature
2941+
when a given set of font families is used. Effectively, they define a mapping
2942+
of &#x27e8;family, feature, ident&#x27e9; &rarr; &#x27e8;values&#x27e9;
2943+
where &#x27e8;values&#x27e9; are the numeric indices used for specific
2944+
features defined for a given font.
2945+
2946+
<!-- Original (CSS2 syntax) text from Fonts 3, for checking
2947+
2948+
2949+
<p>In terms of the grammar, this specification defines the following productions:</p>
2950+
2951+
<pre><dfn>font_feature_values_rule</dfn>
2952+
: <i>FONT_FEATURE_VALUES_SYM</i> <a href="https://www.w3.org/TR/CSS21/grammar.html#scanner"><i>S</i></a>* <i>font_family_name_list</i> <a href="https://www.w3.org/TR/CSS21/grammar.html#scanner"><i>S</i></a>*
2953+
'{' <a href="https://www.w3.org/TR/CSS21/grammar.html#scanner"><i>S</i></a>* <i>feature_value_block</i>? [ <a href="https://www.w3.org/TR/CSS21/grammar.html#scanner"><i>S</i></a>* <i>feature_value_block</i>? ]* '}' <a href="https://www.w3.org/TR/CSS21/grammar.html#scanner"><i>S</i></a>*
2954+
;
2955+
2956+
<dfn>font_family_name_list</dfn>
2957+
: <i>font_family_name</i> [ <a href="https://www.w3.org/TR/CSS21/grammar.html#scanner"><i>S</i></a>* ',' <a href="https://www.w3.org/TR/CSS21/grammar.html#scanner"><i>S</i></a>* <i>font_family_name</i> ]*
2958+
;
2959+
2960+
<dfn>font_family_name</dfn>
2961+
: <a href="https://www.w3.org/TR/CSS21/syndata.html#tokenization"><i>STRING</i></a> | [ <a href="https://www.w3.org/TR/CSS21/syndata.html#tokenization"><i>IDENT</i></a> [ <a href="https://www.w3.org/TR/CSS21/grammar.html#scanner"><i>S</i></a>* <a href="https://www.w3.org/TR/CSS21/syndata.html#tokenization"><i>IDENT</i></a> ]* ]
2962+
;
2963+
2964+
<dfn>feature_value_block</dfn>
2965+
: <i>feature_type</i> <a href="https://www.w3.org/TR/CSS21/grammar.html#scanner"><i>S</i></a>*
2966+
'{' <a href="https://www.w3.org/TR/CSS21/grammar.html#scanner"><i>S</i></a>* <i>feature_value_definition</i>? [ <a href="https://www.w3.org/TR/CSS21/grammar.html#scanner"><i>S</i></a>* ';' <a href="https://www.w3.org/TR/CSS21/grammar.html#scanner"><i>S</i></a>* <i>feature_value_definition</i>? ]* '}' <a href="https://www.w3.org/TR/CSS21/grammar.html#scanner"><i>S</i></a>*
2967+
;
2968+
2969+
<dfn>feature_type</dfn>:
2970+
<a href="https://www.w3.org/TR/CSS21/syndata.html#tokenization"><i>ATKEYWORD</i></a>
2971+
;
2972+
2973+
<dfn>feature_value_definition</dfn>
2974+
: <a href="https://www.w3.org/TR/CSS21/syndata.html#tokenization"><i>IDENT</i></a> <a href="https://www.w3.org/TR/CSS21/grammar.html#scanner"><i>S</i></a>* ':' <a href="https://www.w3.org/TR/CSS21/grammar.html#scanner"><i>S</i></a>* <a href="https://www.w3.org/TR/css3-values/#integer-value"><i>&lt;integer&gt;</i></a> [ <a href="https://www.w3.org/TR/CSS21/grammar.html#scanner"><i>S</i></a>* <a href="https://www.w3.org/TR/css3-values/#integer-value"><i>&lt;integer&gt;</i></a> ]*
2975+
;
2976+
</pre>
2977+
2978+
<p>The following new token is introduced:</p>
2979+
2980+
<pre>@{F}{O}{N}{T}{-}{F}{E}{A}{T}{U}{R}{E}{-}{V}{A}{L}{U}{E}{S} {return <dfn>FONT_FEATURE_VALUES_SYM</dfn>;}
2981+
</pre>
2982+
2983+
-->
2984+
2985+
<pre class=prod>
2986+
@font-feature-values = @font-feature-values &lt;family-name&gt;# { &lt;rule-list&gt; }
2987+
2988+
&lt;family-name&gt; = &lt;string&gt; | &lt;custom-ident&gt;+
2989+
2990+
&lt;feature-value-block&gt; = &lt;feature-type&gt; { &lt;declaration-list&gt; }
2991+
2992+
&lt;feature-type&gt; = @stylistic | @historical-forms | @styleset | @character-variant
2993+
| @swash | @ornaments | @annotation
2994+
2995+
&lt;feature-value&gt; = &lt;integer&gt;+
2996+
</pre>
2997+
2998+
Feature value blocks are handled as
2999+
at-rules,
3000+
they consist of everything up to the next block or
3001+
semi-colon, whichever comes first.
3002+
3003+
The font family list is a comma-delimited list of
3004+
font family names that match the definition of &lt;family-name&gt;
3005+
for the 'font-family!!property' property.
3006+
This means that only named font families are allowed, rules that
3007+
include generic or system fonts in the list of font families are
3008+
syntax errors. However, if a user agent defines a generic font to be a
3009+
specific named font (e.g. Helvetica), the settings associated with
3010+
that family name will be used. If syntax errors occur within the font
3011+
family list, the entire rule must be ignored.
3012+
3013+
Within feature value blocks,
3014+
the feature type is '@' followed by the
3015+
name of one of the <em>font specific</em> property values
3016+
of 'font-variant-alternates' (e.g. ''@swash''). The
3017+
identifiers used within feature value definitions follow the rules of
3018+
CSS user identifiers and are case-sensitive. They are unique only for
3019+
a given set of font families and feature type.
3020+
The same identifier used with a different feature type
3021+
is treated as a separate and distinct value. If the same identifier is defined
3022+
multiple times for a given feature type and font family,
3023+
the last defined value is used. Values associated
3024+
with a given identifier are limited to integer values 0 or greater.
3025+
3026+
When syntax errors occur within a feature value
3027+
definition, such as invalid identifiers or values, the entire feature value
3028+
definition must be omitted, just as syntax errors in
3029+
style declarations are handled. When the feature type
3030+
is invalid, the entire associated
3031+
feature value block must be ignored.
3032+
3033+
<div class="example">
3034+
<p>Rules that are equivalent given syntax error handling:</p>
3035+
<pre>@font-feature-values Bongo {
3036+
@swash { ornate: 1; }
3037+
annotation { boxed: 4; } /* should be @annotation! */
3038+
@swash { double-loops: 1; flowing: -1; } /* negative value */
3039+
@ornaments ; /* incomplete definition */
3040+
@styleset { double-W: 14; sharp-terminals: 16 1 } /* missing ; */
3041+
redrum /* random editing mistake */
3042+
}</pre>
3043+
3044+
<p>The example above is equivalent to:</p>
3045+
3046+
<pre>@font-feature-values Bongo {
3047+
@swash { ornate: 1; }
3048+
@swash { double-loops: 1; }
3049+
@styleset { double-W: 14; sharp-terminals: 16 1; }
3050+
}</pre>
3051+
</div>
3052+
3053+
<p>If multiple ''@font-feature-values'' rules are defined for
3054+
a given family, the resulting values definitions are the union of the
3055+
definitions contained within these rules. This allows a set of named
3056+
values to be defined for a given font family globally for a site and
3057+
specific additions made per-page.
3058+
</p>
3059+
3060+
<div class="example">
3061+
<p>Using both site-wide and per-page feature values:</p>
3062+
<pre>
3063+
site.css:
3064+
3065+
@font-feature-values Mercury Serif {
3066+
@styleset {
3067+
stacked-g: 3; /* "two-storey" versions of g, a */
3068+
stacked-a: 4;
3069+
}
3070+
}
3071+
3072+
page.css:
3073+
3074+
@font-feature-values Mercury Serif {
3075+
@styleset {
3076+
geometric-m: 7; /* alternate version of m */
3077+
}
3078+
}
3079+
3080+
body {
3081+
font-family: Mercury Serif, serif;
3082+
3083+
/* enable both the use of stacked g and alternate m */
3084+
font-variant-alternates: styleset(stacked-g, geometric-m);
3085+
}</pre>
3086+
</div>
3087+
3088+
<div class="example">
3089+
<p>Using a commonly named value allows authors to use a single style rule
3090+
to cover a set of fonts for which the underlying selector is different for
3091+
each font. If either font in the example below is found, a circled number
3092+
glyph will be used:
3093+
</p>
3094+
3095+
<pre>@font-feature-values Taisho Gothic {
3096+
@annotation { boxed: 1; circled: 4; }
3097+
}
3098+
3099+
@font-feature-values Otaru Kisa {
3100+
@annotation { circled: 1; black-boxed: 3; }
3101+
}
3102+
3103+
h3.title {
3104+
/* circled form defined for both fonts */
3105+
font-family: Taisho Gothic, Otaru Kisa;
3106+
font-variant: annotation(circled);
3107+
}</pre>
3108+
</div>
3109+
3110+
<h4>Multi-valued feature value definitions</h4>
3111+
3112+
Most <em>font specific</em> 'font-variant-alternates' property
3113+
values take a single value (e.g. 'swash'). The 'character-variant'
3114+
property value allows two values and 'styleset' allows an unlimited
3115+
number.
3116+
3117+
For the styleset property value, multiple values indicate the style
3118+
sets to be enabled. Values between 1 and 99 enable OpenType features
3119+
<span class="tag">ss01</span> through <span class="tag">ss99</span>.
3120+
However, the OpenType standard only officially defines
3121+
<span class="tag">ss01</span> through <span class="tag">ss20</span>.
3122+
For OpenType fonts, values greater than 99 or equal to 0 do not
3123+
generate a syntax error when parsed but enable no OpenType features.
3124+
3125+
3126+
<pre class="example">@font-feature-values Mars Serif {
3127+
@styleset {
3128+
alt-g: 1; /* implies ss01 = 1 */
3129+
curly-quotes: 3; /* implies ss03 = 1 */
3130+
code: 4 5; /* implies ss04 = 1, ss05 = 1 */
3131+
}
3132+
3133+
@styleset {
3134+
dumb: 125; /* &gt;99, ignored */
3135+
}
3136+
3137+
@swash {
3138+
swishy: 3 5; /* more than 1 value for swash, syntax error */
3139+
}
3140+
}
3141+
3142+
p.codeblock {
3143+
/* implies ss03 = 1, ss04 = 1, ss05 = 1 */
3144+
font-variant-alternates: styleset(curly-quotes, code);
3145+
}</pre>
3146+
3147+
For character-variant, a single value between 1 and 99 indicates
3148+
the enabling of OpenType feature <span class="tag">cv01</span> through
3149+
<span class="tag">cv99</span>. For OpenType fonts, values greater than
3150+
99 or equal to 0 are ignored but do not generate a syntax error when parsed
3151+
but enable no OpenType features. When two values are listed, the first
3152+
value indicates the feature used and the second the value passed for
3153+
that feature. If more than two values are assigned to a given name, a
3154+
syntax error occurs and the entire
3155+
feature value definition</i> is
3156+
ignored.
3157+
3158+
<pre class="example">@font-feature-values MM Greek {
3159+
@character-variant { alpha-2: 1 2; } /* implies cv01 = 2 */
3160+
@character-variant { beta-3: 2 3; } /* implies cv02 = 3 */
3161+
@character-variant { epsilon: 5 3 6; } /* more than 2 values, syntax error, definition ignored */
3162+
@character-variant { gamma: 12; } /* implies cv12 = 1 */
3163+
@character-variant { zeta: 20 3; } /* implies cv20 = 3 */
3164+
@character-variant { zeta-2: 20 2; } /* implies cv20 = 2 */
3165+
@character-variant { silly: 105; } /* &gt;99, ignored */
3166+
@character-variant { dumb: 323 3; } /* &gt;99, ignored */
3167+
}
3168+
3169+
#title {
3170+
/* use the third alternate beta, first alternate gamma */
3171+
font-variant-alternates: character-variant(beta-3, gamma);
3172+
}
3173+
3174+
p {
3175+
/* zeta-2 follows zeta, implies cv20 = 2 */
3176+
font-variant-alternates: character-variant(zeta, zeta-2);
3177+
}
3178+
3179+
.special {
3180+
/* zeta follows zeta-2, implies cv20 = 3 */
3181+
font-variant-alternates: character-variant(zeta-2, zeta);
3182+
}</pre>
3183+
3184+
<div class="figure"><img alt="Matching text on Byzantine seals using character variants" src="images/byzantineseal.png" /><p class="caption">Byzantine seal text displayed with character variants</p></div>
3185+
3186+
<div class="example">
3187+
<p>In the figure above, the text in red is rendered using a font containing
3188+
character variants that mimic the character forms found on a Byzantine seal
3189+
from the 8th century A.D. Two lines below is the same text displayed in
3190+
a font without variants. Note the two variants for U and N used on the
3191+
seal.</p>
3192+
3193+
<pre>@font-feature-values Athena Ruby {
3194+
@character-variant {
3195+
leo-B: 2 1;
3196+
leo-M: 13 3;
3197+
leo-alt-N: 14 1;
3198+
leo-N: 14 2;
3199+
leo-T: 20 1;
3200+
leo-U: 21 2;
3201+
leo-alt-U: 21 4;
3202+
}
3203+
}
3204+
3205+
p {
3206+
font-variant: discretionary-ligatures
3207+
character-variant(leo-B, leo-M, leo-N, leo-T, leo-U);
3208+
}
3209+
3210+
span.alt-N {
3211+
font-variant-alternates: character-variant(leo-alt-N);
3212+
}
3213+
3214+
span.alt-U {
3215+
font-variant-alternates: character-variant(leo-alt-U);
3216+
}
3217+
3218+
&lt;p>ENO....UP͞RSTU&lt;span class="alt-U">U&lt;/span>͞&lt;span class="alt-U">U&lt;/span>ΚΑΙTỤẠG̣IUPNS&lt;/p>
3219+
3220+
&lt;p>LEON|ΚΑΙCONSTA|NTI&lt;span class="alt-N">N&lt;/span>OS..|STOIBAṢ.|LIṢROM|AIO&lt;span class="alt-N">N&lt;/span>&lt;/p>
3221+
</pre>
3222+
</div>
29003223

29013224
<h3 id="font-variant-east-asian-prop">
29023225
East Asian text rendering: the 'font-variant-east-asian' property</h3>
@@ -3771,7 +4094,7 @@ Preinstalled Fonts and User-Installed Fonts</h3>
37714094

37724095
Users may 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 expect the presence of user-installed fonts, because there is no guarantee any user will have performed the action to install a specific font. User Agents may choose to ignore User-Installed Fonts for the purpose of the <a href="#font-matching-algorithm">Font Matching Algorithm</a>.
37734096

3774-
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 targetting these Operating Systems may wish to use these fonts' family names inside ''font-family'' properties.
4097+
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 targetting these Operating Systems may wish to use these fonts' family names inside 'font-family!!property' properties.
37754098

37764099
<h3 id="system-font">
37774100
System Font</h3>
153 KB
Loading

0 commit comments

Comments
 (0)