03.字符显示
03.字符显示
- 字体是从
CSS1就开始支持的功能,在CSS2开始支持下载网络字体。但CSS无法完全控制字体展示效果,如果字体无法正常加载或系统不支持对应的字体格式,显示的效果和设计的效果是不一样的
3.1 字体族
font-family允许你通过给定一个有先后顺序的,由字体名或者字体族名组成的列表来为选定的元素设置字体属性值用逗号隔开,浏览器会选择列表中第一个该计算机上有安装的字体,或者是通过
@font-face指定的可以直接下载的字体,如果字体不可用,那么就会用浏览器默认的字体代替/* 提供一个字体栈,将依次查找可用的字体作为最终字体 */ p { font-family: Helvetica, "Trebuchet MS", Verdana, sans-serif; }如果字体不止一个单词,需要使用引号包裹
网页安全字体:是指在绝大多数操作系统中都预先安装的字体。在1996年由微软提出的Core fonts for the Web为绝大多数的操作系统设计了一些共用字体,之后在不断变化,当前
windows和mac预装字体和普及率列表见css fontsCSS定义了5个常用的字体名称:serif,sans-serif,monospace,cursive和fantasy,当使用这些通用名称时,使用的字体完全取决于每个浏览器,而且它们所运行的每个操作系统也会有所不同- 浏览器会尽力提供一个看上去合适的字体,如果未找到将提供衬线字体,通常是
Time New Roman serif,sans-serif和monospace是比较好预测的,默认的情况应该比较合理cursive和fantasy是不太好预测的,建议使用它们的时候应该稍微注意一些,多多测试

字体类别 - 浏览器会尽力提供一个看上去合适的字体,如果未找到将提供衬线字体,通常是
3.2 web fonts
web字体:允许下载自定义字体,以允许更多不同的、自定义的文本样式@font-face首次出现于CSS2,假设你希望使用的字体没有广泛安装,借助@font-face,可以定义一个字体族,对应服务器上的字体文件,用户代理将下载对应文件,用于渲染文字,就好像电脑上已经安装了这个字体一样@font-face { /* 标识符,对应的引用名称 */ font-family: "SwitzeraADF"; /* 获取的资源信息列表,format可选 */ /* 通过local指定使用用户安装字体列表中的字体族名称,如果没有再下载 */ src: local("SwitzeraADF"), url("SwitzeraADF-Regular.otf") format("opentype"); } /* 兼容性写法 */ @font-face { font-family: "ciclefina"; /* 为了兼容IE9及以下,这些IE6-8只能获取第一个资源 */ /* 现代浏览器都无法使用eot格式 */ src: url("fonts/cicle_fina-webfont.eot"); src: /* 添加?#iefix,修复IE6-8错误的问题,通过解析错误避免多字体列出时的解析问题,这些内容不会被IE6-8读取 */ url("fonts/cicle_fina-webfont.eot?#iefix") format("embedded-opentype"), /* 剩下的将新的格式放在前面 */ url("fonts/cicle_fina-webfont.woff2") format("woff2"), /* chrome、firefox */ url("fonts/cicle_fina-webfont.woff") format("woff"), /* chrome、firefox、opera、Safari, Android, iOS 4.2+*/ url("fonts/cicle_fina-webfont.ttf") format("truetype"), /* iOS 4.1- */ url("fonts/cicle_fina-webfont.svg#ciclefina") format("svg"); }如果提供了format将跳过无法使用的字体后缀,否则将依次下载,在下载完成后且可用之后,字体才会发生变化
支持的字体格式
| 值 | 格式 |
|---|---|
| embedded-opentype | EOT(Embedded OpenType) |
| opentype | OTF(OpenType) |
| svg | SVG(ScalableVectorGraphics) |
| truetype | TTF(TrueType) |
| woff | WOFF(WebOpenFontFormat) |
其他字体描述符:支持对一个字体族名称定义多个不同的字体描述和不同的资源文件,在合适的时候使用特定的字体效果
- 这些描述符在定义文字的
font属性时也能使用,和这里对应
描述符 默认值 说明 font-style normal 区分常规、斜体和倾斜字型 font-weight normal 区分不同的字重(例如加粗) font-stretch normal 区分不同的字符宽度(例如紧缩和加宽) font-variant normal 区分众多字形变体(例如小号大写字母) font-feature-settings normal 直接访问OpenType的低层特性(例如启用连字) unicode-range U+0-10FFFF 定义指定字体中可用的字符范围 可以通过对字体的各种字体风格文件分别使用对应描述符声明,让一个字体族支持多种描述符
- 这些描述符在定义文字的
3.3 字体风格
- 大部分字体风格都可以通过
font指定,font相当于许多字体属性的合并,这种合并在CSS中很常见,需要注意的是,对于在合并属性中未设置的值都将重置为初始值- 必须包含
font-size和font-family - 可以选择性包含
font-style、font-variant、font-weight、font-stretch、line-height font-style,font-variant和font-weight必须在font-size之前font-variant只可以使用CSS 2.1定义的值,即normal和small-capsfont-stretch必须是单个关键字值line-height必须跟在font-size后面,由“/”分隔,例如“16px/3”font-family必须最后指定
- 必须包含
3.3.1 字重font-weight
一般来说,字重越大,字体越黑越粗。许多字体族设置了很多变体,字形相同但字重各不相同,常见变体后缀有
Light、Regular、Medium、Bold、Extra Bold工作方式:
CSS中为字重设计了100到900的整百关键字,对应字体设计中的九级字重,一般Regular对应400,如果没有Regular,且只有一个变体Medium,那Medium对应400如果字体族的字重小于9个,就会以既定方式填补空缺
- 如果100-300有值未分配,为其分配比大一级的字重更细的变体(如果没有就与大一级相同)
- 如果600-700有值未分配,为其分配比小一级的字重更粗的变体(如果没有就与小一级相同)
- 如果500或400未分配,与400或500对应变体相同,如果两个都未分配,先考虑比400略小的变体,如果也没有分配,再考虑比500略大的变体
- 所有字重关键字可以在MDN查看,常用的关键字如下
- normal:正常粗细,与
400等值 - bold:加粗,与
700等值 - lighter:比从父元素继承来的值更细,如果已是最细则相同
- bolder:比从父元素继承来的值更粗,如果已是最粗则相同
- normal:正常粗细,与
3.3.2 字体大小font-size
font-size是设置字体大小的CSS属性,更改字体大小还会更新字体大小相关的长度单位,例如em、ex等,可以通过以下方式指定值- 通过绝对大小、相对大小或
math关键字之一 - 通过相对长度单位或绝对长度单位,必须是正数
- 通过绝对大小、相对大小或
- 绝对大小关键字有
xx-small、x-small、small、medium、large、x-large、xx-large、xxx-large,这些都是基于用户默认的字体大小,通过指定的缩放倍数缩放后的字体大小在的
CSS1-3版本,设计的缩放倍数完全不相同,未来不确定是否会再发生变化 - 相对大小
larger、smaller,字体大小将相对父元素变化,大致按照上面用于区分绝对大小关键字的比率 - math:还在实验中的新关键字,根据字体所在数学深度值进行缩放,数学深度值是数学公式容器中的元素相当于顶级容器的深度概念,对数学公式的输出有帮助
对无障碍的考量
如果希望更好地支持无障碍,字体大小最好完全依赖用户默认的字体大小值,比如绝对大小关键字或在不修改根元素字体大小情况下使用em、rem和%值
3.3.3 字形font-style
font-style允许你选择font-family字体下的italic或oblique样式,默认值为normalItalic字体是特殊样式的字体oblique字体是默认字体的斜体版本- 如果
Italic或oblique其中一个字体的变体不存在,这两个效果相同 - 如果
Italic或oblique字体变体都不存在,将通过人工倾斜常规字体的字形来模拟
3.3.4 字体合成font-synthesis
font-synthesis属性确定浏览器是否应合成缺失的字体系列中的粗体、斜体和小型大写字体等效果,许多非标准西方字体没有这些,通过添加下列值获取对应模拟,都不选填none,默认全选weight:合成粗体style:合成斜体small-caps:合成小型大写英文字体(效果像让大写字体只占小写字体x的行高)position:上下标(到2024年11月仅火狐支持)
实际上是font-synthesis-*系列属性的结合,每个属性都支持auto(开启)和none(关闭)
3.3.4 字体拉伸font-stretch
某些字体系列提供了额外的字体外观,比如紧凑字体外观(字符比正常宽度窄)和扩展字体外观(字符比正常宽度宽),可以使用
font-stretch从此类字体中选择紧凑或扩展字体。如果你使用的字体不提供紧凑或扩展字面,则此属性无效属性支持关键字或百分比形式,对应关系如下图

字体拉伸属性
3.3.5 字距font-kerning
- 设置是否使用字体文件中的字距,可选属性值如下,默认值为
autoauto:浏览器来决定是否使用字体字距。比如,一些浏览器会在小字体的情况下禁用字距,因为这会使得文本可读性下降normal:必须应用字体中的字距信息none:禁用字体中的字距信息
3.3.6 字体变形font-variant
- 是大量
font-variant-*属性的结合,默认值为normal,可以填入下列属性的对应值修改对应属性,主要有这些属性
对opentype字体的额外配置支持
font-feature-settings: '字体属性名' 值;属性用于控制OpenType字体中的高级印刷功能,设置opentype属性参数,如果未提供值,值默认为1,对于字体变形支持的属性配置应该优先考虑使用字体变形,所有字体属性见opentype注册属性
3.4 文本属性
3.4.1 行高line-height
- 用于设置文本元素的行高,常用于设置文本节点的行间距,属性如下,推荐使用倍数
- normal:取决于用户代理
- 无单位数字:根据字体大小乘此倍数
- 长度单位:其中的百分比是根据当前元素的字体大小计算的
3.4.2 字体方向
字体前进方向
writing-mode:决定字体的书写方向,默认是横向- 横向书写
horizontal-tb - 纵向书写
vertical-lr,下一行出现在本行的右侧 - 纵向书写
vertical-rl,下一行出现在本行的左侧,文字起始位置将出现在容器右侧
- 横向书写
文本方向
direction- 对于从右到左书写的语言(如希伯来语或阿拉伯语),应将该属性设置为
rtl - 对于从左到右书写的语言(如英语和大多数其他语言),则应将该属性设置为
ltr
dir属性
一般情况下网页的文本方向应该通过
html标签的dir属性指定,而不是使用direction直接指定全局的文本方向,因为dir是一个语义化属性,浏览器相关工具比如朗读、翻译,搜索引擎都能很好地理解,direction属性一般用于排版微调文本方向变化对布局坐标系的影响
- 像
direction、writing-mode,甚至是flex-direction这样对文本方向和渲染布局方向有影响的属性,最终都会影响到布局坐标系- 最明显的就是
srcollbar滚动条初始位置的变化,这些方向将修改默认元素的位置,也会影响到滚动条的初始位置。虽然通过scrollTop这样的js属性读取到的初始都是0,但是初始位置确实被修改地和阅读方向一致了,也就是初始可以看到文本开始或布局开头的元素
- 最明显的就是
方向对布局坐标系的影响<div class="container"> <div class="box" id="normal"> <div class="info"></div> <div class="content">默认布局<br>horizontal-tb</div> </div> <div class="box" id="reverse"> <div class="info"></div> <div class="content">flex<br>column-reverse</div> </div> <div class="box" id="rtl"> <div class="info"></div> <div class="content">direction: rtl</div> </div> <div class="box" id="vertical"> <div class="info"></div> <div class="content">writing-mode: vertical-rl</div> </div> </div>const boxes = document.querySelectorAll('.box'); function updateInfo(el) { const info = el.querySelector('.info'); info.textContent = `scrollTop: ${el.scrollTop.toFixed(0)} | scrollLeft: ${el.scrollLeft.toFixed(0)}`; } boxes.forEach(el => { updateInfo(el); el.addEventListener('scroll', () => updateInfo(el)); });.container { display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; } .box { border: 2px solid #666; height: 150px; width: 200px; overflow: auto; position: relative; } .content { width: 400px; height: 400px; background: linear-gradient(to bottom right, #fff, #111); } .box:hover { &>.info { display: block; } } .info { position: sticky; float: left; top: 4px; left: 4px; background: rgba(255,255,255,0.8); font-size: 12px; padding: 2px 6px; border-radius: 4px; display: none; } /* 场景特定样式 */ #reverse { display: flex; flex-direction: column-reverse; } #rtl { direction: rtl; } #vertical { writing-mode: vertical-rl; }:::
- 对于从右到左书写的语言(如希伯来语或阿拉伯语),应将该属性设置为
文档类型定义的设计者设计时需要定义
Unicode字符最终的文本方向unicode-bibi,这个字体方向网页设计人员一般不应该复写。这个值与Unicode双向算法有关,这个算法定义了每种字符对应的方向性,比如每种语言自身方向决定的rtl和ltr字符,还有会随周围字符方向而改变自身文本方向的部分符号normal:这是默认值。文本的方向性由字符本身的Unicode双向算法来决定。也就是说,大部分拉丁字母文字会从左到右显示,而像阿拉伯语或希伯来语这样的文字则会从右到左显示embed:文本方向性由自身字符来决定,不会受到外部文本方向性的影响。有助于在更大的文本流中嵌入具有不同方向性的文本块isolate:相比embed提供了更严格的隔离。除了方向性,isolate还会阻止周围的文本影响嵌入文本的格式设置(如连字符等)。这有助于确保嵌入的文本块在视觉上和格式上都与外部文本完全分离bidi-override:这个值会覆盖Unicode双向算法,强制文本按照HTML或CSS中指定的方向渲染。这允许在更大的文本流中嵌入具有不同方向性的文本块plaintext:使元素中的文本像无格式的纯文本一样进行双向算法处理。这主要用于模拟纯文本编辑器的行为
unicode-bidi与direction是仅有的两个不受all简写影响的属性,all属性可以覆写除了direction和unicode-bidi外的所有属性值
3.4.3 字体位置text-align
text-align设置行内内容水平对齐方式start:如果内容方向是左至右,则等于left,反之则为rightend:如果内容方向是左至右,则等于right,反之则为leftleft:行内内容向左侧边对齐right:行内内容向右侧边对齐center:行内内容居中justify:文字向两侧对齐,将内容隔开,使其左右边缘与行框的左右边缘对齐,对最后一行无效justify-all:和justify一致,但是强制使最后一行两端对齐match-parent:和inherit类似,区别在于start和end的值根据父元素的direction确定,并被替换为恰当的left或right值
center是很简单的水平居中对齐方式,如果需要垂直居中对齐,最简单的方法是使用flex对齐,并设置align-items为center
3.4.4 空白符处理
white-space属性设置空白符和换行的处理方式,默认值为normalnormal:连续的空白符会被合并。源码中的换行符会被当作空白符来处理。并根据填充行框盒子的需要来换行nowrap:和normal一样合并空白符,但阻止源码中的文本换行pre:连续的空白符会被保留。仅在遇到换行符或<br>元素时才会换行pre-wrap:连续的空白符会被保留。在遇到换行符或<br>元素时,或者根据填充行框盒子的需要换行pre-line:连续的空白符会被合并。在遇到换行符或<br>元素时,或者根据填充行框盒子的需要换行break-spaces:和pre-wrap一样,但任何空白符都会占空间- 支持
white-space-collapse属性和text-wrap属性合并作为值
属性值 换行符 空格和制表符 文本换行 行末空格 行末的其他空白分隔符 normal合并 合并 换行 移除 挂起 nowrap合并 合并 不换行 移除 挂起 pre保留 保留 不换行 保留 不换行 pre-wrap保留 保留 换行 挂起 挂起 pre-line保留 合并 换行 移除 挂起 break-spaces保留 保留 换行 换行 换行 挂起应该是指会保留,但不显示
3.4.5 文本断行
text-overflow可以设置结尾方式,比如设置...结尾,属性不可继承clip: 截断ellipsis: 添加省略号string: 添加自定义字符串,目前仅Firefox支持
