字体提供了包含字符的视觉表现的资源。在最简单的等级中,其包含由字符编码到表示这些字符的形状(被称为字形)的映射信息。根据一组标准字体属性被分入一个字体家族的字体共享一个通用设计风格。在一个家族中,表现指定字符的形状,可以通过笔画粗细、倾斜或相对宽度而彼此改变。一个给定的字体外观是为这些属性的一个唯一组合而设计的。对于文本的给定范围,在渲染这些文本时使用CSS字体属性选择所使用的字体家族及家族中的字体外观。作为一个简单的例子,为了使用Helvetica字体的粗体形式,可以使用:
body{font-family:Helvetica;font-weight:bold;}
字体资源可以是本地、安装于运行用户代理的系统中、或可下载的。对于本地字体资源,描述信息可以直接从字体资源中获得。对于可下载的字体资源(有时为到Web字体的引用),描述信息在对字体资源的引用中。
通常字体的家族不会为字体属性的每个可能变化包含一个独立的外观。CSS字体选择机制描述如何将一个给定的CSS字体属性集匹配到一个给定的字体外观。
本节所包含的内容会被用作其他章节中所描述的问题和情况的背景。它应当仅被认为是参考信息。
全球各地的传统排版存在不同,所以不存在一种唯一的方法对所有字体按照语言和文化进行分类。即使是普通的拉丁字母,也存在多种可能的变种:
字形分解的不同是区别字体的一种方法。对于拉丁字体,字符的主要笔划端点处的花边或衬线,可以用于区分字体。类似的区别也存在于非拉丁字体,即锥形笔划和均匀笔划。
字体包含字母形态和将字符映射到这些字母形态所需的数据。通常这可能是一个简单的一对一映射,但也可能会是更复杂的映射。与发音符号集合使用可能会产生潜在的字母形态变种:
一段字符序列可以被表示为一个单独的字形,这边称为连字:
视觉转换基于文本上下,这对于欧洲语言可能是可选的,但在正确选择诸如阿拉伯语这类语言时确实必须的;下面的lam和alef字符在连续出现时必须连接在一起。
这些相对复杂的形状转换需要字体的附加数据。
一系列拥有不同格式变种的字体外观通常会在字体家族中进行分组。在最简单的情况下,一个标准外观会辅以粗体和斜体外观,但也可以拥有更多。这通常包括字母形态笔划的粗细、重量、或字母形态整体的比例、或宽度的变种。在下面的例子中,每个字母使用了Univers字体家族中的一种不同的字体外观。宽度自上至下递增,重量自左至右递增:
创建一个支持多种脚本的字体是不同的任务;设计师需要理解使用不同脚本的文化传统,进而了解字母形态将以何种形式公用一个相同的主题。许多语言经常会公用一个通用脚本,这些语言之间可能会拥有显要的格式区别。波斯语、乌尔都语、斯拉夫语公用阿拉伯语脚本,不仅是俄语。
一个字体的字符映射定义了该字体中字符到字形的映射。如果一个文档中包含的字体没有在该字体中明确指定的字符映射,用户代理可能会使用系统字体备用程序来定位适当的字体。如果没有找到适当的字体,用户代理将会选择某种形式的“丢失字形”字符。备用程序可以发生在没有明确指定字体或作者没有明确指出文档的编码时。
显示一个字符的特定字体外观是由字体系列和其他指定在元素上的字体属性所决定的。这种结果允许设置相互独立的改变。
该属性指定了一个优先序列,其中包含字体家族名称或通用家族名称。与其他CSS属性不同,其值的各个组成部分之间以逗号分隔。用户代理迭代穿过家族名称列表,指定匹配一个包含待渲染字符的字形的有效字体。这允许在不同平台拥有的有效字体存在差异,以及单个字体所支持的字符范围有差异。
一个字体家族名称仅指定一个给一个字符外观集合的名称,其比指定个体外观。字体的可用性在下面给出,Futura可以匹配,但FuturaMedium不能:
考虑下面的例子:
示例:
body{font-family:Helvetica,Verdana,sans-serif;}
如果Helvetica有效,则在渲染时使用该字体家族。如果Helvetica和Verdana均不可用,则将使用用户地理定义的无衬线字体(sansserif)字体。
存在两种字体家族名称的类型:
<家族名称>
<通用家族>
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:Hawaii5-0,sans-serif;
如果一个标识符序列作为字体家族名称给出,则其计算值是被转换为字符串的名称,在转换时,会将所有标识符通过一个单独的空格连接起来。
为了避免转码错误,我们建议把包含空格、数字或除连字符外标点字符的字体家族名称用引号包围:
body{font-family:"NewCenturySchoolbook",serif}
某些字体格式允许字体包含字体名称的多个本地化形式。用户代理必须识别并正确匹配所有这些名称,这些操作独立于底层平台的本地化、所使用的系统API和文档编码:
所有五个通用字体家族被定义要求存在于所有CSS实现中(不必为它们映射五个不同的实际字体)。用户代理应当为通用字体家族提供合理的默认选择,该选择在底层技术允许的范围内尽可能的表现每个家族中字体。我们鼓励用户代理允许用户选择通用字体的替代选择。
衬线(serif)
无衬线(sans-serif)
手写体(cursive)
幻想(fantasy)
幻想字体主要用于装饰包含幽默地表示字符的字体。它们不包括不表示实际字符的Pi或图片字体。
等宽(monospace)
等宽字体的唯一要求是所有字形都拥有相同的固定宽度。它们经常被用于显示计算机代码示例。
其值的意义如下:
100至900
bold
bolder
lighter
使用并非九阶的缩放比例的字体格式应当将其缩放比例映射到CSS缩放比例,使得400大致符合将会标为Regular、Book、Roman的外观;700大致符合将会标为Bold的外观。或者从样式名推断其重量,使其大致符合上述宽度比例。缩放比例是相对的,所以一个拥有较大重量的外观不可能更轻。如果样式名被用于推断重量,则应当着重处理与本地化信息交叉的样式名称中的变种。
尽管该实践对于印刷业来说并不完善,但是在缺少实际较重重量的字形的情况下,通常由用户代理合成较重重量的字形。为了符合样式匹配的要求,这些字形必须被当做其存在于家族之中。
许多脚本没有在显示文本时与normal外观混用草书形式的传统。中文、日语和韩语字体几乎没有斜体或倾斜的外观。支持多种脚本的字体有时会在支持斜体的外观中忽略某些诸如阿拉伯语的脚本的字形集。用户代理应当小心地跨外观进行字符映射。
<绝对字号>
[xx-small|x-small|small|medium|large|x-large|xx-large]
<相对字号>
[larger|smaller]
<长度>
<百分比>
基于可读性原因,用户代理在应用这些指导方针的时候,应当避免产生的字号造成在计算机上显示时每EM单位少于9像素。
在CSS1中,每个相邻索引之间的缩放因子是1.5,使用体验显示其过大。在CSS2中,对于计算机屏幕每个相邻索引之间的缩放因子是1.2,这仍然会在小字号上产生问题。对每个索引之间新的缩放因子的改变会提供更好的可读性。
p{font-size:12pt;}blockquote{font-size:larger}em{font-size:150%}em{font-size:1.5em}
下面的样式定义Verdana为期望的字体,但如果Verdana不可用,则使用Futura或Times。
p{font-family:Verdana,Futura,Times;}
Loremipsumdolorsitamet,...
Verdana具有较高的纵横比,小写字母与大写字母的比例相对较高,所以较小字号的字体能够清晰的显示。Times具有较低的纵横比,所以如果使用后备字体,较小字号的字体较Verdana会具有较低的清晰度。
此属性允许编码人员为一个元素指定一个纵横值,这能够有效的保持首选字体的x轴高度,而不考虑首选字体是否被替代。其值的意义如下:
none
<数值>
c=(a/a')s
其中:
p{font-family:Futura;font-size:500px;}span{border:solid1pxred;}.adjust{font-size-adjust:0.5;}
b
右侧的盒子稍大于左侧的,所以改字体的纵横值稍小于0.5。
p{font:12pt/14ptsans-serif}p{font:80%sans-serif}p{font:x-large/110%"newcenturyschoolbook",serif}p{font:bolditaliclargePalatino,serif}p{font:normalsmall-caps120%/120%fantasy}p{font:oblique12pt"HelveticaNeue",serif;font-stretch:condensed}
在第二个规则中,字号百分比值(‘80%’)涉及其父元素的字号。在第三个规则中,行高百分比(‘110%’)涉及该元素自身的字号。
下列各值引用系统字体:
caption
icon
menu
message-box
small-caption
系统字体可能仅被设置为一个整体,即字体家族、字号、重量、样式等,它们同时被设置。如果需要,之后可以个别的修改这些值。如果包含特定特征的字体不存在于给定的平台上,则用户代理应当智能替代(例如一个较小版本的‘caption’字体可能被用于‘smallcaption’字体)、或替换为用户代理默认字体。对于一个规则字体,如果(对于系统字体)任何独立属性不是操作系统可用的用户首选项中的一部分,则这些属性应当被设为它们的初始值。
button{font:300italic1.3em/1.7em"FBArmada",sans-serif}buttonp{font:menu}buttonpem{font-weight:bolder}
如果在特定系统上用于下拉菜单的字体恰好是,例如,9-point的Charcoal,其重量为600,则作为BUTTON后裔的P元素的显示将与下列规则产生的效果相似:
buttonp{font:6009ptCharcoal}
buttonp{font-style:normal;font-variant:normal;font-weight:600;font-size:9pt;line-height:normal;font-family:Charcoal}
该属性控制是否允许用户代理在字体家族缺少粗体或斜体外观是字形合成粗体或倾斜的字体外观。如果没有指定‘weight’,则用户代理禁止合成粗体外观;如果没有指定‘style’,则用户代理禁止合成斜体外观。值‘none’禁止所有合成外观。
下面的样式规则不能使用合成的倾斜阿拉伯语:
*:lang(ar){font-synthesis:none;}
@font-face规则允许到字体的链接,该字体在需要的时候会自动激活。这允许编码人员选择更接近该页面设计目标的字体,而不必在选择字体的时候被全平台可用字体集所限制。一个字体描述符集定义了一个字体资源的位置(既可以是本地位置也可以是远程位置)以及个体外观的样式特征。多个@font-face规则可以用于产生拥有不同外观的字体家族。使用CSS字体匹配规则,用户代理可以有选择的仅仅下载这些外观中指定的部分文本。
@font-face@规则的一般格式是:
@font-face{<字体描述>}
其中<字体描述>的格式是:
descriptor:value;descriptor:value;[...]descriptor:value;
每个@font-face规则指定为所有字体描述符指定一个值,这可以是隐含的也可以是明确的。对于那些规则中没有给出明确值的情况,将使用本规范中为每个描述符列出的初始值。这些描述符仅在定义它们的@font-face的上下文中适用,不会被应用于文档语言元素。没有关于描述符适用于的元素或子元素是否会继承这些值的概念。如果一个描述符在给定的@font-face规则中出现了多次,则指使用最后指定的值,忽略所有该描述符之前的值。
为了使用一个名为Gentium的可下载字体:
用户代理将下载Gentium,并在渲染段落元素中的文本时使用。如果由于某些原因服务器上的字体不可用,则使用默认的serif字体。
一个给定的@font-face规则集定义了一组对包含文档可用的字体。可以使用多个规则定义额一个拥有大外观集合的家族。如果使用这些规则定义的字体能够通过字体匹配,则这些字体的优先级高于其他系统可用字体。
已下载的字体仅在引用它们的文档中可用,激活这些字体的过程不应该使它们对于其他应用或没有直接链接到相同字体的文档可用。用户代理实践可能会在渲染其他不存在可用字体的文档中的字符时方便的使用已下载的字体作为系统字体后备程度一部分的。这可能会造成安全漏洞,因为一个页面中的内容可以影响另一个页面,有时可被攻击者用作攻击媒介。这些限制不会影响缓存行为,字体的缓存与其他资源的缓存方式相同。
不支持@font-face规则的用户代理将忽略从开花括号到毕花括号之间的内容。此@规则符合CSS的向前兼容解析要求,解析器可以没有错误的忽略这些规则。所有没有被特定用户代理认可或实现的描述符都必须被忽略。@font-face规则需要一个font-family和src描述符,如果缺少它们之一则必须忽略该@font-face规则。
在用户代理拥有被限制的平台资源或实现能够禁用可下载字体资源的情况下,@font-face规则必须直接被忽略;本规范中定义的个体描述符的行为不应被改变。
此描述符定义了将用于所有CSS字体家族名称匹配的字体架子名称,其重新定义了隐含字体数据中包含的字体家族名称。如果该字体家族名称与用户环境中可用的字体家族相同,则其有效的在使用该样式表的文档中隐藏了这个底层的字体。这允许web编码任意自由的选择字体家族的名称,而不必担心其会与给定的用户环境中现场的字体家族名称冲突。加载字体的错误不会影响字体名称的匹配行为。如果一个用户代理将平台字体别名规则应用到由@font-face规则所定义的字体家族名称上,则这个用户代理是不符合规范的。
该描述符指定包含字体数据的资源。这是必需的,不论字体是可下载的或是本地安装的。其值是有序的、逗号分隔的外部引用或本地已安装字体外观名称的列表。若字体需要用户代理迭代遍历引用列表集合,则使用第一个能够成功激活的。包含无效数据的字体或没有找到的本地字体外观将会被忽略,且用户代理将会载入列表中的下一个字体(禁止平台替换给定的字体)。
与CSS中的其他URI相似,此URI可以是局部的,在这种情况下其相对于包含该@font-face规则的样式表的位置。对于SVG字体,该URL指向一个包含SVG字体定义的文档中的元素。如果元素引用被省略,则意味着引用到第一个定义的字体。类似地,对于能够包含超过一个字体的字体容器格式,一个给定的@font-face规则必须载入并仅能载入一个字体。片段标识符用于表示要载入哪个字体。如果一个容器格式没有定义片段标识符方案,实践应当从1开始索引这些方案(即“font-collection#1”为第一个字体、“font-collection#2”为第二个字体)
src:url(fonts/simple.ttf);/*相对于样式表位置加载simple.ttf*/src:url(/fonts/simple.ttf);/*从绝对位置加载simple.ttf*/src:url(fonts.svg#simple);/*加载id为‘simple’的SVG字体*/
外部引用由一个URI、以及一个紧跟的可选的用于描述该URI所引用的字体资源的格式的提示。这个格式提示包含一个逗号分隔的列表,列表中的元素是表示众所周知的字体格式的格式字符串。如果格式提示都是不支持或未知的字体格式,则符合规范的用户代理必须跳过对这些字体资源的下载。如果没有提供格式提示,则用户代理应当下载这些字体资源。
/*如果WOFF自己可用则进行载入,否则使用OpenType字体*/@font-face{font-family:bodytext;src:url(ideal-sans-serif.woff)format("woff"),url(basic-sans-serif.ttf)format("opentype");}
格式字符串由本规范定义:
由于TrueType和OpenType的常见用法相互重叠,所以格式提示“truetype”和“opentype”必须被认为拥有相同意义;一个“opentype”格式提示并不意味着改字体包含PostscriptCFF样式的字形数据或者其包含OpenType布局信息(更多背景信息参见附录A)。
如果编码人员希望使用给定字体的本地可用副本,并且在其不存在的时候下载该字体,则可以使用local()。本地已安装的
/*Gentium的规则外观*/@font-face{font-family:MyGentium;src:local(Gentium),/*使用本地可用的Gentium*/url(Gentium.ttf);/*否则进行下载*/}
名称可以可选的使用引号包围。对于OpenType和TrueType字体,其字符串用于在本地可用字条的名称表中仅匹配Postscript名称或完整的字体名称。使用哪一个会因平台或字体而变,所以用户代理应当同时包含这些名称,以保持其能够跨平台匹配。
/*Gentium的粗体外观*/@font-face{font-family:MyGentium;src:local(GentiumBold),/*完整字体名称*/local(Gentium-Bold),/*Postscript名称*/url(GentiumBold.ttf);/*否则进行下载*/font-weight:bold;}
这也允许引用那个属于不能被引用的大家族中的外观。
使用本地字体或引用一个其他文档中的SVG字体:
@font-face{font-family:Headline;src:local(Futura-Medium),url(fonts.svg#MyGeometricModern)format("svg");}
为在不同平台上的本地日文字体创建一个别名:
@font-face{font-family:jpgothic;src:local(HiraKakuPro-W3),local(Meiryo),local(IPAPGothic);}
引用一个不能被匹配的大家族中的字体外观:
@font-face{font-family:HoeflerTextOrnaments;/*与HoeflerTextRegular拥有相同的字体属性*/src:local(HoeflerText-Ornaments);}
由于不能匹配本地化的完整名称,一个拥有如下标题样式规则的文档将总是使用默认serif字体进行显示,而无论特定系统的位置参数是否被设为芬兰:
@font-face{font-family:SectionHeader;src:local("ArialLihavoitu");/*ArialBold的芬兰语完整名称,匹配应当失败*/font-weight:bold;}h2{font-family:SectionHeader,serif;}
@font-face{font-family:MainText;src:url(gentium.eot);/*为了兼容较旧的不符合规范的用户代理*/src:local("Gentium"),url(gentium.ttf);/*重写src描述符*/}
该描述符定义了字符外观的特征,其被用于匹配样式到指定外观的过程中。对于被定义拥有多个@font-face规则的字体家族,用户代理可以下载所有家族中的外观,也可以使用这些描述符有选择地下载匹配文档中使用的实际样式的字体外观。这些描述符的值与相应的字体属性相同,但不允许使用相对关键字(‘bolder’和‘lighter’)。如果忽略了这些描述符,则假定为默认值。
这些字体外观样式属性的值被用于替代底层字体数据所隐含的样式。这允许编码人员灵活的组合外观,即使是在源字体数据拥有不同安排的情况下。实现了合成粗体和倾斜的用户代理必须在字体描述符暗示其需要的情况下仅应用合成样式,而不是基于字体数据所暗示的样式属性。
Unicode范围值使用十六进制值编写且不区分大小写。每个都由“U+”作为前缀并重复,不连续的范围以逗号分隔。逗号之前或之后的空格将被忽略。有效的字符码在0至10FFFF之间(包含)变化。一个单独的范围有三种基本形式:
任何不符合上述三种形式的范围都被认为会解析出错并忽略该描述符。有一个单独码位组成的区间范围是有效的。使用“”且没有起始数字的范围(如:U+)也是有效的,其被认为是在问号之前有一个单独的0(因此,“U+”=“U+0”=“U+0000-0FFF”)。“U+”不是一个语法错误,但“U+0”是。范围是可以重叠的,但向下的区间范围(如:U+400-32f)是无效的且会被忽略但不会出现解析错误;它们不会影响在同一个范围列表中的其他范围。范围会被剪裁到Unicode码位的范围(当前包括0-10FFFF);完全超出集合的范围会被忽略。没有有效范围的描述符将被忽略。用户代理可能会将这些范围列表标准版的列入一个不同但表示相同字母码位集合的列表。
字符范围可以是底层字体完整字符映射的子集。映射字符到字体上时所使用的有效Unicode范围是Unicode范围指定的和底层字体字符映射的交集。这意味着编码人员不需要精确的定义一个字体的Unicode范围,可以使用字符中所定义的码位的稀疏集的广泛范围。超出Unicode范围的码位将被忽略,而不论该字体是否包含该码位的字形。下载了超出Unicode范围所定义码位的用户代理被认为是不符合规范的。相同的,在显示某个字符时使用了Unicode范围定义没有包含该字符的字体的用户代理也被认为是不符合规范的。
特定语言或字符范围的例子:
Unicode范围:U+A5;
Unicode范围:U+0-7F;
Unicode范围:U+590-5ff;
Unicode范围:U+A5,U+4E00-9FFF,U+30,U+FF00-FF9F;
BBC提供多语言新闻服务,其中许多语言没有被所有平台很好地支持。使用@font-face规则,BBC可以为这些语言提供字体,如同这些字体已经通过手动下载。
@font-face{font-family:BBCBengali;src:url(fonts/BBCBengali.ttf)format("opentype");unicode-range:U+00-FF,U+980-9FF;}
科技文档通常需要更广泛的符号。STIX字体项目旨在通过标准方式提供一个支持广泛科技排版的字体。下面的例子展示了如何使用提供了许多Unicode中数学和技术范围内字形的字体:
@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;}
多个拥有相同家族和样式描述符但Unicode范围不同的@font-face规则可以被用于为不同脚本创建混合多个字体中字形的混合字体。这可以用于结合只包含单一脚本字形的字体(如拉丁语、希腊语、斯拉夫语)或者可以被编码任意用来将一个字体分割为常用字符和稀有字符。由于用户代理只会下载需要的字体,所以这可以帮助缩减页面贷款。
如果Unicode范围与一个拥有相同家族和样式描述符的@font-face集合重叠,则这些规则的顺序是它们被定义顺序的逆序;即首先在最后定义的规则中检查给定的字符。
下面的例子展示了编码人员如何使用其他字体中的字形覆盖日语中的拉丁字符所使用的字形。第一个规则没有指定范围,所以其默认的为全部范围。第二个规则指定了范围,由于其为后定义的,所以其覆盖了原有范围。
@font-face{font-family:JapaneseWithGentium;src:local(MSMincho);/*没有指定范围,所以其默认的为全部范围。*/}@font-face{font-family:JapaneseWithGentium;src:url(../fonts/Gentium.ttf);unicode-range:U+0-2FF;}
通过分隔拉丁语、日语和其他字符到不同的字体文件,最优化一个家族的贷款:
/*备用字体-大小:4.5MB*/@font-face{font-family:DroidSans;src:url(DroidSansFallback.ttf);/*没有指定范围,所以其默认的为全部范围。*/}/*日语字形-大小:1.2MB*/@font-face{font-family:DroidSans;src:url(DroidSansJapanese.ttf);unicode-range:U+3000-9FFF,U+ff;}/*拉丁语、希腊语、斯拉夫语以及一些标点符号-大小:190KB*/@font-face{font-family:DroidSans;src:url(DroidSans.ttf);unicode-range:U+000-5FF,U+1e00-1fff,U+2000-2300;}
对于简单的拉丁语文本,则只会下载拉丁语字符的字体:
body{font-family:DroidSans;}
Thisisthat
在这种情况下,用户代理首先检查包含拉丁语字符的字体(DroidSans.ttf)的Unicode范围。因为所有上述字符都在U+0-5FF范围内,则用户代理下载该字体并使用该字体显示这些文本。
随后,考虑被用作简体字符的文本():
This⇨that
用户代理在此首先检查只包含拉丁语字符的字体的Unicode范围。由于U+2000-2300包含箭头码位(U+21E8),则用户代理下载该字体。对于那些拉丁语字体不能匹配字形的字符,该字体所用于的Unicode范围不能有效匹配该码位。所含用户代理评估日语字体。日语字体的Unicode范围U+3000-9FFF和U+FF,不包含U+21E8,所以用户代理不会下载日语字体。随后考虑备用字体。备用字体的@font-face规则没有定义Unicode范围,所以其值为默认的全部Unicode码位范围。下载备用字体并使用该字体显示箭头字符。
@font-face规则的设计,是为了允许对字体的延迟加载。字体将仅会在被文档需要时才会下载。一个样式表可以包含@font-face规则并将其作为一个只有一个选择集被使用的字体库;用户代理只能下载适用于给定页面的样式规则中引用的字体。那些下载@font-face规则中所定义的所有字体而不考虑这些字体实际上是否会在页面中使用的用户代理被认为是不符合规范的。在某些情况下,可能会因为字体后备的要求而下载字体,在这种情况下,如果字体被列在字体列表中,但不会在给定文本中实际使用,用户代理也可以下载该字体。
@font-face{font-family:GeometricModern;src:url(font.ttf);}p{/*页面包含p元素是将下载该字体*/font-family:GeometricModern,sans-serif;}h2{/*页面包含h2元素时可能会下载该字体,即使Futura在本地可用*/font-family:Futura,GeometricModern,sans-serif;}
如果文本内容在可下载字体可用前加载完成,则用户代理在显示文本时可以像可下载字体资源不可用时那样,或者也可以透明地使用备用字体显示文本以避免使用备用字体的文本闪烁。如果字体下载失败,用户代理必须显示文本,只留下透明文本被认为是不符合规范的行为。我们建议编码人员在其字体列表中使用与可下载字体垂直度量上相近的备用字体,以尽可能地避免出现大的页面回流。
选择字体的程度包括迭代由font-family属性所确定的字体家族、基于其他属性选择适当的字体外观以及确定指定字符对于的字形是否存在。
上面的程序总会在处理包含Unicode字符在内的文本是执行,使用传统编码的文档被假定为在匹配字体之前已被转换。对于同时包含传统编码和Unicode字符映射的字体,传统编码字符映射的内容在进行字体匹配过程中不得起到任何作用。
如果文本包含Unicode变种选择器,则需要特殊处理。对于每个字符+变种选择器配对,如果第一个包含基础字符字形的字体也包含变种选择器指定的变种的字形,则用户代理必须显示变种字形而不是默认的。如果第一个包含基础字符字形的字体不包含变种选择器对的字形,则显示默认字形。
如果给出的字符是一个私有使用区的Unicode码位且字体列表中的字体均不包含该码位的字形,则用户代理必须显示某种形式的缺失字形符号而不是尝试显示该码位的备用系统字体。在匹配替换字符U+FFFD时,用户代理可以跳过字体匹配过程而直接显示某种形式的缺失字符符号,它们不需要显示从字体匹配过程中选择的字体中获得的字形。
通常,一个家族中的字体都拥有相同或相似的字符映射。此过程被设计用来处理那些包含字符映射差异很大的外观的字体家族。但是,编码人员应当警惕使用这些字体可能会导致意外的结果。一个仅在家族中收缩比例斜体外观中可用的特殊字符可能会在字体属性暗示应当显示粗体扩张比例字形时仍被使用。
此过程的最佳情况是允许提供一个严格重视此算法的实现行为。匹配发生在一个定义良好的顺序下,以保证其结果尽可能的跨用户代理保持一致,给出一个完全一致的可用字体和显示技术集。
问题:如何匹配字形簇需要明确指定。
上面的算法与CSS2.1的差异在几个关机位置。这些修改能够更好的反映实际字体匹配行为的跨浏览器实现。
与CSS2.1字体匹配算法的差异:
注意CSS选择器语法可以有助于创建语言敏感的排版。举例说明,某些中文和日文字符统一地具备相同的Unicode码位,即使两种语言的抽象字形并不相同。
*:lang(ja-jp){font:90014pt/16pt"HeiseiMinchoW9",serif;}*:lang(zh-tw){font:80014pt/16.5pt"LiSung",serif;}
这选择拥有指定语言(日语或繁体中文)的任意元素使用适当的字体。
现代字体技术支持各种先进的排版和语言特定的字体特性。使用这些特性,一个独立的字体可以为针对指定语言的连字、上下文和格式的替代、表格式和旧式的数字、小型大写字母、自动分数、花饰以及替代提供字形。为了允许编码人员控制这些字体功能,我们在CSS3中扩展了font-variant属性,现在,它的功能更像是一系列能够控制文本字体特性的属性的速记形式。
用于显示拉丁文本的简单字体使用一个非常基础的处理模型,字体包含一个将给定字符映射到该字符的字形上的字符映射。后续字符的字形定位在文本中的下一个位置。诸如OpenType和AAT的字体格式使用更丰富的处理模型,可以选择给定字符的字形,其定义也不仅仅依靠一个单独的字符,其还会参考周围的字符以及语言、脚本和文本激活的特性。字符特性可能是特定脚本需要的,或者是推荐默认启动的,或者它们可能是编码人员控制下使用的文本特性。
文本字体特性可以广义的被分为两类,一类会影响字形模型与周围上下文的协调,这包括字符间距和连字特性;以及类似于小型大写字母、下标/上标以及替换特性等影响模型选择的。
下面列出的font-variant的子属性用于控制这些文本字体特性;它们不会控制显示某一脚本所需的特性,这包括显示阿拉伯语或印度语文本时使用的OpenType特性。它们影响字形选择和定位,它们不影响字体匹配章节中描述的字体选择(除非为了与CSS2.1兼容的情况)。
为了保证跨用户代理的行为一致,为某些属性列出了等价的OpenType属性并且必须被认为是符合规范的。在使用其他字体格式时,这些应当作为将CSS字体特性属性的值映射到指定字体特性上的指导。
问题:OpenType文档没有指定完整的默认特性集合。应当把它们列入规范的附录?
OpenType还支持语音特定的字形选择和定位,这使得文本可以在语言规定了特殊显示行为的情况下正确的进行显示。语言通常会公用一个通用脚本,但某些字母的模型可能会在不同语言之间存在差异,例如俄语和保加利亚语文本中的某些斯拉夫字母变种。在拉丁文本中,通常在显示“fi”时会使用去掉“i”上的点的明确的fi连字。但是,在诸如会同时使用拥有点的i和没有点的i的土耳其语的语言中,不使用该连字或者使用在i上方包含点的特殊版本,是非常重要的。下面的例子中展示了西班牙语、意大利语和法语正字法中基于文本惯例的语言特定变种。
我们要求用户代理从‘lang’属性的值中推断OpenType语言系统,并在选择和定位OpenType字体的字形时使用推断的值。如果没有定义‘lang’属性,则必须使用默认OpenType语言系统。
问题:应当允许用户代理推断OpenType语言还是仅仅直接使用默认语言系统?
独立值的意义如下:
common-ligatures
no-common-ligatures
discretionary-ligatures
no-discretionary-ligatures
historical-ligatures
no-historical-ligatures
contextual
no-contextual
在显示复杂脚本是所需的必要的连字不受上面所提到的设置所影响,包括‘none’(OpenType特性:rlig)。
此属性用于启动上标和下标字形的排版。这将替换在相同EM盒子中作为默认字形而设计的字形,并将其布局在与默认字形相同的基线上而不会调整基线的大小或位置。它们的设计是为了在不影响行高的情况下与周围的文本更协调、更具可读性。
因为上标和下标的语义性质,如果给定的一段文本的值是‘sub’或‘super’而且变种字形对于这段文本中的字符并不全部可用,则模拟字形是使用默认字型的缩小形式的所有字符合成而得的。这是为了避免在同一段文本中混合使用变种字形和合成字形,这两种字形不能保证能够正确地相互对齐。
编码人员应当注意字体通常只为其所支持字符的子集提供上标和下标字形。通常拉丁数字的上标和下标字形是可用,而符号和字母字符的字形较少提供。如果所使用的字体没有体会上标或下标中所包含的所有字符对应的替换字形,此属性定义的合成备用规则保证了总是能够显示上标和下标,但这并不保证其能符合编码人员的预期。
基于这些限制,我们不推荐在用户代理样式表中使用font-variant-position。编码人员应当在指定字体值支持少量字符的上标或下标的情况下使用此属性。
典型用户代理sub元素的默认样式:
sub{vertical-align:sub;font-size:smaller;line-height:normal;}
使用font-variant-position指定上标排版并同时能够在老的用户代理上显示上标:
@supports(font-variant-position:sub){sub{vertical-align:inherit;font-size:100%;line-height:inherit;font-variant-position:sub;}}
指定控制大写形式。
各值的意义如下:
normal
small-caps
all-small-caps
petite-caps
all-petite-caps
unicase
titling-caps
此属性允许选择替换用于小型或细小大写字母或标题的字形。这些字形的设计是为了能够更好的与周围的默认字形混合,为了保持重量和可读性这些文本简单的被调整大小以适应这一目的。
这些字形的可用性基于字体特性列表中是否定义了给定的特性。用户代理可以有选择地针对每个脚本进行判断,但不能针对每个字符进行判断。
为了与周围的文本相协调,在启用了这些特性而不是由用户代理模拟小型大写字母时,字体可能会为不区分大小写的字符替换替代字形,禁止为不区分大小写的码位模拟替代字形。
如果使用大小写转换来模拟小型大写字母,则大小写转换应当与‘text-transform’属性所使用的相匹配。
作为最后的手段,缩小默认字体中的大写字母字形可能会替换small-caps字体中的字形,这使得文本以全大写字母形式出现。
斜体显示引用,其中第一行使用samall-caps:
blockquote{font-style:italic;}blockquote:first-line{font-variant:small-caps;}
I'llbehonor-boundtoslapthemlikeahaddock.
指定控制数组形式。
lining-nums
oldstyle-nums
proportional-nums
tabular-nums
下面的例子展示了这些不同的属性将如何结合起来影响支持这些特性的字体的表格数据的显示。
diagonal-fractions
stacked-fractions
ordinal
slashed-zero
一个用自动分数和就是数值显示的简单的牛排腌制配方:
.amount{font-variant-numeric:oldstyle-numsdiagonal-fractions;}
牛排腌制:
2汤匙橄榄油 1汤匙柠檬汁 1汤匙酱油 11/2汤匙干燥的碎洋葱 21/2茶匙意大利调味料 - 盐&胡椒
将肉与腌料混合是其完全覆盖,在冰箱中放置几个小时或一整夜。
对于任意给定的字符,除了该字符的默认字形外,字体还可以提供各种额外的替代字形。此属性提供了对这些替换字形选择的控制。
对于存在多种可用替代品的情况,编码人员使用下面描述的@font-feature-values规则定义一个
stylistic(
historical-forms
styleset(
character-variant(
swash(
ornaments(
annotation(
下面的例子中展示了花饰Q的情况,花饰可以使用这些样式规则指定:
@font-feature-valuesJupiterSans{@swash{delicate:1;flowing:2;}}h2{font-family:JupiterSans,sans-serif;}/*在h2标题中显示第二种花饰变种*/h2:first-letter{font-variant-alternates:swash(flowing);}
Quick
@font-feature-values规则的语法定义如下:
如果为一个家族定义了多个@font-feature-values规则,其结果是联合这些规则。这允许为一个字体家族在整站范围定义一组名值对,并在各个页面进行追加。如果为一个font-variant值定义了多次相同的
使用通用的已命名值,可以让编码人员使用一个样式规则覆盖一系列底层选择器不同的字体。如果下面例子中能够找到任一字体,则将会使用一个圆圈数字字形:
@font-feature-valuesTaishoGothic{@annotation{boxed:1;circled:4;}}@font-feature-valuesOtaruKisa{@annotation{circled:1;black-boxed:3;}}h3.title{/*圆圈来自于定义的两个字体*/font-family:TaishoGothic,OtaruKisa;font-variant:annotation(circled);}
对于styleset属性值,多个值表示启用样式集。值1至99表示启用OpenType特性ss01至ss99。但是,OpenType标准只正式定义了ss01至ss20。大于99或等于0的值将被忽略,但在解析时不会产生语法错误。
@font-feature-valuesMarsSerif{@styleset{alt-g:1;/*意味着ss01=1*/curly-quotes:3;/*意味着ss03=1*/code:45;/*意味着ss04=1,ss05=1*/}@styleset{dumb:125;/*>99,忽略*/}@swash{swishy:35;/*swash超过一个值,语法错误*/}}p.codeblock{/*意味着ss03=1,ss04=1,ss05=1*/font-variant-alternates:styleset(curly-quotes,code);}
对于character-variant,一个单独的1至99的值表示启用OpenType特性cv01至cv99。对于OpenType字体,大于99或等于0的值将被忽略,但解析时不会产生语法错误。如果列出的两个值,则第一个值表示使用的特性,第二个值传递给该特性。如果两个值名称表示相同底层特性的不同设置,则使用最后设置的。
@font-feature-valuesMMGreek{@character-variant{alpha-2:12;}/*意味着cv01=2*/@character-variant{beta-3:23;}/*意味着cv02=3*/@character-variant{epsilon:536;}/*超过两个值,语法错误,忽略*/@character-variant{gamma:12;}/*意味着cv12=1*/@character-variant{zeta:203;}/*意味着cv20=3*/@character-variant{zeta-2:202;}/*意味着cv20=2*/@character-variant{silly:105;}/*>99,忽略*/@character-variant{dumb:3233;}/*>99,忽略*/}#title{/*使用第三个替代beta、第一个替换gamma*/font-variant-alternates:character-variant(beta-3,gamma);}p{/*zeta-2在zeta之后,意味着cv20=2*/font-variant-alternates:character-variant(zeta,zeta-2);}.special{/*zeta在zeta-2之后,意味着cv20=3*/font-variant-alternates:character-variant(zeta-2,zeta);}
在上图中,红色文本是使用包含字符变种的字体显示的,该字符变种模仿从公园8世纪的拜占庭印章上发现的字符形式。之后的两行则是使用不含变种的字体显示的相同文本。请注意印章上所使用的U和N的两个变种。
@font-feature-valuesAthenaRuby{@character-variant{leo-B:21;leo-M:133;leo-alt-N:141;leo-N:142;leo-T:201;leo-U:212;leo-alt-U:214;}}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);}
ENO....UPRSTU
LEON|ΚΑΙCONSTA|NTI
允许控制东亚文本的替代和大小。
jis78
jis83
jis90
jis04
simplified
traditional
full-width
proportional-width
ruby
/*启用小型大写字母和第二种花饰替代*/font-feature-settings:"smcp","swsh"2;
特性标记值的语法如下:
font-feature-settings:"dlig"1;/*dlig=1启用酌情连字*/font-feature-settings:"smcp"on;/*smcp=1启用小型大写字母*/font-feature-settings:'c2sc';/*c2sc=1启用大写及小写字母的小体大写字母*/font-feature-settings:"liga"off;/*liga=0禁用通用连字*/font-feature-settings:"tnum",'hist';/*tnum=1,hist=1启用表格数字和历史形式*/font-feature-settings:"tnum""hist";/*无效,需要一个逗号分隔的列表*/font-feature-settings:"palin"off;/*好主意,但标记名无效*/font-feature-settings:"PKRN";/*PKRN=1启用自定义特性*/font-feature-settings:dlig;/*无效,标记必须为一个字符串*/
虽然目前仅为OpenType特性标记进行定义,但其他支持字体特性的现代字体格式也可能会在未来增加。如果可能,为其他字体格式定义的特性应当遵循注册OpenType标签的模式。
下面的日语文本将使用半角kana字符显示:
body{font-feature-settings:"hwid";/*半角OpenType特性*/}
毎日カレー食べてるのに、飽きない
Hikimsekeyfiolaraktutuklanamaz,alkonulanamazveyasürülemez.Madde9
Никojчoвeкнeмaдaбидeпoдлoжeннaпрoизвoлнoaпсee,притвoрилипрoгoнувae.Члeн9
在显示此处的马其顿文本时,将使用塞尔维亚语排版惯例,假设指定字体支持塞尔维亚语。
通用和字体特定的字体特性属性设置按照下面的顺序提升优先级进行处理。此顺序用于生成一个影响给定文本的字体特性列表组合。
对于字体特性设置列表组合中包含多个对于相同特性的值的情况,使用最后一个值。若字体缺少对指定底层字体特性的支持,显示字体时则按照没有启用该字体特性处理;不会出现备用字体,并且除非明确为指定属性指出,不会视图合成该特性。
下面的样式中,数字在段落中被显示为比例值,在prices表格中被显示为等宽值。
body{font-variant-numeric:proportional-nums;}table.pricestd{font-variant-numeric:tabular-nums;}
如果在@font-face规则中使用了font-variant描述符,其只适用于该规则所定义的字体。
@font-face{font-family:BodyText;src:local("HiraMaruPro-W4");font-variant:proportional-width;font-feature-settings:"ital";/*拥有中日韩文本特性的拉丁斜体*/}body{font-family:BodyText,serif;}
如果可用,则会使用日语字体“HiraginoMaruGothic”。在显示文本时,日语假名将会按比例分隔,同时拉丁文本将用斜体字显示。在使用备用的衬线字体显示文本时,将使用默认的显示属性。
在下面的例子中,只会在可下载字体上启用酌情连字,但是在class为“special”的span元素上禁用:
@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;}
向上面的@font-face追加酌情样式规则:
body{font-family:main,Helvetica;}span{font-feature-settings:"dlig";}span.special{font-variant-ligatures:no-discretionary-ligatures;}
@font-face和@font-feature-values规则的内容可以通过下面到CSS对象模型的扩展来访问。
CSSFontFaceRule接口表示一个@font-face规则。
interfaceCSSFontFaceRule:CSSRule{attributeDOMStringfamily;attributeDOMStringsrc;attributeDOMStringstyle;attributeDOMStringweight;attributeDOMStringstretch;attributeDOMStringunicodeRange;attributeDOMStringvariant;attributeDOMStringfeatureSettings;}
CSSRule接口如下扩展:
partialinterfaceCSSRule{constunsignedshortFONT_FEATURE_VALUES_RULE=14;}
CSSFontFeatureValuesRule接口表示一个@font-feature-values规则。
interfaceCSSFontFeatureValuesRule:CSSRule{readonlyattributeDOMStringfamilyList;readonlyattributeDOMStringvalueText;};
familyList,类型DOMString,只读
valueText,类型DOMString,只读
因为通过@font-face规则定义的字体会在需要时加载,页面可能会在测量文本元素或者显示某种形式的临时用户界面状态时需要知道字体在何时完成下载。
为了让字体加载能够被显式地跟踪,需要将下列事件目标加入到页面的Document中:
partialinterfaceDocument{readonlyattributeFontLoaderfontloader;};
因为@font-face规则定义的字体家族只在其使用时才会家族,内容有时会需要知道字体加载在何时发生。编码人员可以使用这里定义的事件和方法来允许对依赖特定字体可用性的行为进行更多控制。
下列事件处理函数(及其对应的事件处理函数事件类型)必须被FontLoader对象作为IDL属性所支持。
如果用户代理确定需要下载通过文档doc中@font-face规则定义的一个或多个字体,则必须执行下列步骤:
问题:此处应该使用哪种错误类型?
问题:给出的@font-face规则集可能会同时进行载入,“loading”事件的非空值是否有意义?
用户代理完成文档doc中的每个字体载入时,必须执行下列步骤:
用户代理完成文档doc中最后的字体载入时,必须执行下列步骤:
isFontAvailable(font,text)方法必须执行下列步骤:
loadFont(font,text)方法必须执行下列步骤:
notifyWhenFontsReady(fontsReadyCallback)方法必须执行下列步骤:
编码人员应当注意此处的回调仅触发一次,此方法需要在可能的进一步字体载入发生时再次调用。此方法与“loadingdone”事件处理函数的回调方法类似,但在此情景下总是会调用回调,即使因为需要字体已经载入而没有发生加载行为。这是一种简单的方法,来同步字体加载代码,而不必跟踪需要的字体和载入时机。
在所有字体载入完成之后显示文本。
document.fontloader.onloadingdone=function(){varcontent=document.getElementById("content");content.style.visibility="visible";}
在canvas上使用一个可下载字体绘制文本,显式地初始化字体下载并在完成后开始绘制:
functiondrawStuff(){varctx=document.getElementById("c").getContext("2d");ctx.fillStyle="red";ctx.font="50pxMyDownloadableFont";ctx.fillText("Hello!",100,100);}window.onload=function(){document.fontloader.loadFont("50pxMyDownloadableFont");}document.fontloader.onloadingdone=drawStuff;
富文本编辑器应用可能会需要在编辑行为发生之后测量文本元素。由于样式变化可能需要也可能不需要追加下载字体,或者字体可能已经下载,所以测量程序需要发生在字体载入完成之后:
functionmeasureTextElements(){//此时可以使用可下载字体的度量来测量内容}functiondoEditing(){//内容/布局操作可能会造成追加下载字体document.fontloader.notifyWhenFontsReady(measureTextElements);}
本附录包含了其他章节中描述的某些问题或情景的背景。其应当仅作为信息参考。
CSS中的字体属性被设计为独立于底层字体格式而使用;除了常见的TrueType和OpenType字体外,它们还可以用来指定点阵字体、Type1字体和SVG字体。但是TrueType和OpenType格式经常会使编码人员混淆,而且对于在不同平台上的实现提出了挑战。
在许多情况下,在MicrosoftWindows或Linux中使用的字体数据与在Apple的MacOSX下使用的数据存下轻微不同,这是因为TrueType格式允许明确的跨平台变种。这包括字体度量、名称和字符映射数据。
特别的,对于字体家族名称数据的处理不同平台各有不同。对于TrueType和OpenType字体,它们的名称包含在‘name’表之中,其名称记录的ID为1。可以为不同地点存储多个名称,但Microsoft推荐字体总是至少包含美国英语版本的名称。在Windows上,Microsoft决定为了向后兼容,限制家族名称最多四个;对于较大的分组,可以使用“首选家族”(名称ID16)或“WWS家族”(名称ID21)。其他诸如OSX的平台没有这个限制,家族名称可以用于定义所有可能的组。
名称表中的其他数据提供用于唯一标识家族中特定外观的名称。完整字体名称(名称ID4)和Postscript名称(名称ID6)描述一个独立的唯一外观。GillSans家族的粗体外观的完整名称为“GillSansBold”、Postscript名称为“GillSans-Bold”。一个给定外观的完成名称可以有多种本地版本,但Postscript名字总是一个由ASCII字符组成的唯一名称。
对于不同平台,使用不同的名称搜索一个字体。举例说明,使用WindowsGDICreateIndirectFontAPI,可以使用家族或完整名称查找一个外观,而在MacOSX上ATSFontFindFromName和ATSFontFindFromPostScriptNameAPI可以使用完整名称和Postscript名称查找指定外观。在Linux下,fontconfigAPI允许使用所有这些名称查找字体。在平台API自动替代其他字体选择的情况下,可能会需要验证返回的字体与给定名称相匹配。
给定外观的重量可以通过OS/2表的usWeightClass字段确定或者通过样式名称(名称ID2)推测。类似的,宽度可以通过OS/2表的usWidthClass确定或者通过样式名称推测。由于历史原因,使用WindowsGDIAPI对200或更小重量的加粗合成,字体设计师有时会使用OS/2表中的skewed值禁用这些重量。
在显示诸如泰语、阿拉伯语和梵文等使用上下文形状的复杂脚本时,需要只存在于OpenType或AAT字体中的特性。当前,Windows和Linux使用OpenType字体特性支持复杂脚本的显示,而AAT字体特性被用于MacOSX。Apple表示其计划在未来支持使用OpenType字体特性显示复杂脚本。