内容简介:CSS能够在众多的布局标准中脱颖而出的制胜手段就是其强大的文本处理能力,比如最"简单"的盒子边缘文字即将超出就自动换行的能力在CSS流的概念里几乎是天生的,并逐渐成为了行业内的“常规认知”,然而同时代的SVG标准要想让文字换行,还需要你手动处理一下,对于计算机来说,没有什么是与生俱来的,CSS在图文布局方面所定制的许多标准在现在看来其实是非常“人性化”的,本章我们就来深入探索一下CSS的文本处理机制。个人将本章内容分成上中下三个章节,本节主要介绍文本(font)属性相关的知识,下一章则把@font face
CSS能够在众多的布局标准中脱颖而出的制胜手段就是其强大的文本处理能力,比如最"简单"的盒子边缘文字即将超出就自动换行的能力在CSS流的概念里几乎是天生的,并逐渐成为了行业内的“常规认知”,然而同时代的SVG标准要想让文字换行,还需要你手动处理一下,对于计算机来说,没有什么是与生俱来的,CSS在图文布局方面所定制的许多标准在现在看来其实是非常“人性化”的,本章我们就来深入探索一下CSS的文本处理机制。
个人将本章内容分成上中下三个章节,本节主要介绍文本(font)属性相关的知识,下一章则把@font face规则单独作为一章进行讲解,最后一章讲一些处理文本的CSS属性。闲话不多说,让我们来看看font家族有哪些成员,以及这些成员有哪些特性吧。
1.font-size的亲戚line-height&远方亲戚vertical-align
说起font属性,在平时的布局中,最常用的就是font-size属性,说起font-size,我们通常用一个具体的数值去定义字体的大小,然而除了定义字体的大小外,font-size其实还有一大堆亲朋好友,跟font-size有着或远或近的联系,由于跟font-size有染的CSS属性太多,这里只详细介绍部分属性,有些远房亲戚或是平时不怎么用的属性就一笔带过了。
提到文本,就不得不提内联元素,提到内联元素,就不得不提line-height和vertical-align。line-height的部分类别属性是相对于font-size计算的,而vertical-align的百分比属性值又是相对于line-height计算的,因此我们可以利用这个特性实现一些“自适应布局”。例如,下面的CSS代码组合
<div>文字<img src="./删除.png"></div> <style> div { font-size: 20px; line-height:1.5; } div > img { width: 16px; height: 16px; vertical-align: 25%; position: relative; top: 8px; } </style> 复制代码
本例中,line-height:数值的计算值是font-size*数值 = 20px*1.5 = 30px
vertical-align:百分比的计算值是line-height*百分比 = 30px * 25% = 7.5px
在内联元素章节,我们了解了文字的基线时字符x的下边缘,而图片一般以自己的下边缘作为基线,因此图片下边缘默认和中文的两个汉字字形底边缘往上一点的位置对齐,然后我们通过vertical-align:25%(注意这是一个估计值)声明让图片的下边缘和中文汉字的中心线对齐,如下图所示。红线表示中心线
当图片下边缘对齐文字中心线的时候,我们就可以通过transform偏移图片本身,来使得图片的中心线和文字的中心线对齐了,这里我使用了relative相对定位,实现的效果是一样的。
最终我们实现了文字和图标的动态对齐效果(感兴趣的可以尝试修改文字font-size的值进行测试)。
2.font-size的近亲ex、em和rem
为什么要说ex,em和rem是font-size的近亲呢,因为这些单位都是font-size的相对单位,是根据font-size的值进行计算的,并且计算得到的值可以变成一个相对单位用于布局。
ex是字符x的高度,font-size的值越大,ex的计算值也就越大,关于ex的内容,在内联元素那章已经深入探究过,这里不过多介绍了。
下面来看看单位em,顾名思义,em就是字母'M'的宽度?的高度?准确的说,不是。用官方的话讲:em是值一个字模的高度(这里可以参考作者的看法,脑补下活字印刷术的字模)。由于其计算值接近"M"的宽高值,因此称其为em。由于大写的"M"和中文字体都拥有方方正正的特性,因此em也可以被看作是一个中文字的宽度。例如,浏览器默认的font-size是16px,如果div的宽度是160px,那么这个div正好可以放下十个汉字,这里的160px = 10em = 10个汉字。
在本节的开头我标红了一句话,不知大家能否根据这句话做对下面这个例题(反正我是没做对)
<!-- 这可太秀了 --> <span>hello</span> <span>world</span> <style type="text/css"> span{ font-size: 2em; margin: 0 1em; } </style> 复制代码
已知浏览器的默认字体是16px,请问span标签的font-size和margin计算值是多少?
正常思维:font-size:2em = 2* 16px = 32px,margin:1em = 16px 那不就是32px和16px嘛?
然鹅,真相并没有那么简单,来看浏览器给出的真相是什么。
浏览器给出的2em的计算值竟然跟1em的一模一样?
既然浏览器已经给出最终的结果了,那我们就来分析一波为什么1em ===2em?不知你有没有注意到,我在概括ex,em,rem的时候,有个词出现了整整三次,是哪位幸运观众获得了这份殊荣呢—— font-size !为什么这个词出现的频率如此之高呢?因为这个相对计算值非常关键。以上面那道题为例,浏览器在拿到margin:0 1em的时候会做一件什么事情呢?首先他会发现,这里有个相对单位em,既然有em,那margin就得问font-size要值了,此时font-size是2em,那font-size看到em也要找font-size要值?那特么不是死循环了吗?
放心,一个小小的CSS还不至于让浏览器进入死循环,CSS会优先计算font-size:2em = 2*浏览器默认的font-size=2*16px = 32px,然后再告诉margin:0 1em,我算好了,你拿去用吧,因此margin = 0 1em = 1*font-size = 32px。于是最终的计算值,font-size和margin都是32px。
搞明白相对的概念后,我们可以想到利用相对单位做弹性布局,然而em这个单位受到当前上下文的font-size影响,不是特别稳定,为了解决这个局限性,另外一个和font-size密切相关的单位rem就出现了。
rem顾名思义,就是root(根)元素的font-size的相对单位,他只会受根元素font-size大小的影响,因此rem被广泛应用于移动端的弹性布局方案中,虽然rem是根据em衍生出来的,但他们却有完全不同的命运,em本来是主角,如今却被摁在冷板凳上万年上不来台,rem却变成了移动端布局的香饽饽,只能说世事无常鸭~
3.font-size的“偏门”属性
font-size还支持关键字属性,这点恐怕很多人不知道(又包括我了)。font-size的关键字属性分为以下两类
(1)相对尺寸关键字。指相对于当前元素的font-size进行计算
larger:大一点。是big标签的默认font-size。
smaller:小一点。是small标签的默认font-size。
(2)绝对尺寸关键字。与当前元素的font-size无关,仅受浏览器设置的字号影响(注意不是根元素,划重点!浏览器字号怎么设置麻烦自己百度)
绝对尺寸关键字总共有7种,非常大,很大,大,中(medium),小,很小,非常小。
这两个尺寸关键字在不同浏览器的表现各不相同,尤其是相对尺寸关键词,看看就好了,基本没什么使用价值,绝对尺寸关键字,除了C位出道的medium,其他基本都没用。个人认为,了解一下这两个偏门属性就好。
4.特殊的font-size:0与文本隐藏
在PC端的Chrome浏览器下有个12px的字号限制,就是文字的font-size的计算值不能小于12px,当然之前也遇到过有个变态需求非得让我把字体变成10px的,可以尝试用transform:scale()去改变元素大小实现(当然浏览器都规定字号不小于12px了,尽量还是遵循一下)
由于浏览器有字体最小12px的限制,因此你设置font-size:<12px的值均会被当作12px来处理,然而有一个值例外,那就是0,你可以理解为0是一个文字隐藏的关键字,当然他比关键字还厉害一点的是,他真的可以让font-size以0px的值参与计算。然而font-size:0被设计出来之后,跟rem一样,并没有干自己的老本行,而是在一些特殊领域发挥着一些余热,如“如何解决图片底边空白问题”,就可以设置父元素的font-size:0,来消除幽灵空白节点的影响。
5.字体家族族谱管理员font-family
font-family,翻译成中文,就是字体家族,font-family的默认值受操作系统和浏览器的控制,我们常用的Windows和OS系统的默认字体就不一样,同一台系统的Chrome和Firefox浏览器的默认字体也不一样。
font-family除了支持字体名称的关键字外,还支持“字体种类”。常用的字体名称有:font-family:simsun(宋体),font-family:'Microsoft Yahei'(微软雅黑)等。如果字体名称包含空格,一定要用引号包起来。当然font-family也支持对应的中文名称,但是尽量使用英文,以防字体解析失败。
下面我们来探究一下偏冷门的“字体种类”,我个人认为,font-family给字体做了族谱后,还给各种习性相近的家族做了个分类,这个分类就是“字体种类”。MDN上文档分类如下
font-family: serif(衬线字体)、sans-serif(无衬线字体)、monospace(等宽字体) 、cursive(手写字体)、fantasy(奇幻字体)、system-ui(系统字体)
对于中文网站,后面三种字体的应用场景有限,就不过多展开,这里着重介绍一下衬线字体,无衬线字体和等宽字体。
衬线字体和无衬线字体是字体家族中两种比较常见的字体,所谓衬线字体,通俗讲就是笔画开始、结束的地方有额外装饰而且笔画的粗细会有所不同的字体,如“宋体”。而无衬线字体则没有这些额外的装饰,而且笔画的粗细差不多,如现在最常用的“雅黑”字体。要注意,不管是衬线还是无衬线字体,或是上述“字体种类”中的任意一款字体,都有默认的字体关键字,经过个人测试,谷歌浏览器下serif(衬线字体)的默认字体包就是宋体。sans-serif(无衬线字体)的默认字体包就是微软雅黑。当然不同的操作系统和浏览器可能有自己的偏好,因此"字体种类"可以算作是按照操作系统喜好展现哪种字体的一种方式。
下面我们再来讲讲等宽字体的实践价值,所谓等宽字体,一般是针对英文字体而言的,因为中文字体在介绍em的时候就提到了,每个中文字体近似于是等宽高的,然而英文字母的大小写却又很大的不同,如下面这个例子:
<div>iiiiiii</div> <div>MMMMMMM</div> 复制代码
由于markdown编辑器支持标签语言,因此我们可以直接预览最终效果如下 (小提示:你可以通过浏览器直接检查下面的元素看到CSS样式)
iiiiiii
MMMMMMM
其实等宽字体的好处我都不用多说了,我们直接看,我在代码框里打出来的代码,上下就是完全对齐的,要做到这种对齐,就必须让每个字符所占据的位置保持一致,而在浏览器的默认字体下,两行文字所占据的位置就差的有点远了,等宽字体的应用非常多,所谓仁者见仁智者见智,用得到的时候自然就会想到了。
6.细腻的font-weight
font-weight表示“字重”,就是文字的粗细程度,font-weight有两个常用的关键字,normal和bold,事实上除了这两个字面意义上的关键字之外,font-weight还支持以下 关键字 :100/200/300/400/500/600/700/800/900以及相对于父级元素的lighter和bolder。
可能有人怀疑我脑子有问题,为什么不直接写100-900呢?因为,数字100并不是数字,他是关键字,只是叫100罢了,如果你来一个100的亲戚,100.000001,不好意思,font-weight不认识,也不认可。这时候又有人要说了,font-weight:100也没有生效呀,为什么设置了font-weight:100之后字体跟200/300/400没什么区别?这锅就不能甩给浏览器了,浏览器是支持检测这些关键字的,之所以看不到粗细变化,是因为我们系统里缺乏对应粗细的文字,因此通常情况下,我们只用到关键字normal(400)和bold(700)就足够了,如果要看到这种细微的变化,需要我们的操作系统安装这些字体包,当然实际生产环境中你不可能要求用户去按照除了浏览器之外的东西,因此想要解决这个问题,就需要借助@font-face了。这个属性会在后面深入探究,这里不过多展开。
7.font家族其他属性font-style和font-variant
font-style除了支持normal和italic(斜体)外,还支持oblique关键字,事实上这个关键字并没有什么软用,这里小小的做个展开。italic表示引用该字体的斜体字体包,通常情况下,很多文字包并没有单独的斜体包,但有些英文字体包会有斜体字体包,如果招不到斜体字体包,则让字体直接倾斜。oblique关键字的作用就是直接让文字倾斜,因此我说这个关键字没什么软用,通常情况下,斜体字体包会比文字直接侵袭要好看得多,谁会去用oblique呢?
font-variant也是个不符合我国国情的CSS属性,他的作用是实现小体型大写字母,这个属性能让m和M的体型保持一致,这个属性在母语是英文的国家可能用的比较多,对于我们来说就是个鸡肋属性,了解一下即可。
8.深藏不露的font属性
font支持缩写,其语法如下:
[ [ <'font-style'> || <'font-variant'> || <'font-weight'> ]? <'font-size'> [ / <'line-height'> ]? <'font-family'> ] 复制代码
这里我想跳过font缩写的相关介绍,因为这属于CSS的糟粕部分,原文如下:
对于大部分的可缩写属性,缩写并不是个问题。您可以声明你想要的,任何选项都可以缺失,如果没有则会应用初始值。例如list-style和background没有应用的值99%的时间无论如何都不会被继承的,所以值的设置与否无伤大雅。但是,很多排版属性都预期从父辈继承。因此,当你使用font缩写,事情会变得混乱。如果你对该属性的复杂性不熟悉,估计你要抓破脑袋了。换句话说,如果我在body元素上声明文字粗体,我可能本希望里面的文字都继承粗体。结果,一旦应用了缺少font-weight缩写属性的font缩写,文字不是粗体显示的了。
原文到此结束,本人想吐槽font缩写的两个问题,第一,font-family不能省略,font-family那么又臭又长的属性连个默认值都没有,每次缩写都得声明,这也太浪费我时间了。第二,line-height可以省略,但会被继承,也就是你又是漏写了个line-height,这个line-height就重置为normal了,就继承给后代了,这设定也忒.....
综上所述,不建议使用font缩写。
font属性除了缩写用法,还支持关键字属性值,这个恐怕很多人不知道(又包括我了),关键字列表如下
- caption:包含说明文字控件的字体(如按钮,下拉等)。
- icon:标签图标使用的字体,影响所有文件以及文件夹名称字体。
- menu:菜单使用的字体(如下拉菜单和菜单列表)。
- message-box:消息框使用的字体。
- small-caption:标记小控件使用的字体。
- status-bar:窗体状态栏使用的字体。
值得注意的是,声明了font:关键字后,就无需定义font-size,font-family等属性了,因为这些关键字本质上也是一种缩写,已经包含font的各种属性了。
ont关键字在实际使用场景中就是可以让网页跟着系统走,要知道现在已经有很多桌面软件可以修改系统的默认字体了,如果让浏览器能根据用户的“心情”显示对应的字体的话,看起来是不是很智能呢?这里我提供两种方式,让字体随着系统的默认字体改变。第一种,之前提到的font-family字体种类中还有一个被忽略的关键字system-ui,使用示例如下:
html{font-family:system-ui} 或者 html{font:menu} 复制代码
本章的内容到此结束,本来@font face的内容也会放在这一章,但为了保证文章的阅读时间不要过长,打算单独成立一章讲讲@font face。觉得内容有用的点个赞吧~
不忘初心,方得始终
喜欢博主的童鞋可以扫描二维码加博主好友~ 也可以扫中间二维码入驻博主的粉丝群(708637831)~当然你也可以扫描二维码打赏并直接包养帅气的博主一枚。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。