CSS进阶(17)—— CSS中的文本处理(上)

CSS可以在众多的布局标准中脱颖而出的制胜手段就是其强大的文本处理能力,好比最"简单"的盒子边缘文字即将超出就自动换行的能力在CSS流的概念里几乎是天生的,并逐渐成为了行业内的“常规认知”,然而同时代的SVG标准要想让文字换行,还须要你手动处理一下,对于计算机来讲,没有什么是与生俱来的,CSS在图文布局方面所定制的许多标准在如今看来实际上是很是“人性化”的,本章咱们就来深刻探索一下CSS的文本处理机制。css

我的将本章内容分红上中下三个章节,本节主要介绍文本(font)属性相关的知识,下一章则把@font face规则单独做为一章进行讲解,最后一章讲一些处理文本的CSS属性。闲话很少说,让咱们来看看font家族有哪些成员,以及这些成员有哪些特性吧。 html

1.font-size的亲戚line-height&远方亲戚vertical-align

提及font属性,在平时的布局中,最经常使用的就是font-size属性,提及font-size,咱们一般用一个具体的数值去定义字体的大小,然而除了定义字体的大小外,font-size其实还有一大堆亲朋好友,跟font-size有着或远或近的联系,因为跟font-size有染的CSS属性太多,这里只详细介绍部分属性,有些远房亲戚或是平时不怎么用的属性就一笔带过了。 java

提到文本,就不得不提内联元素,提到内联元素,就不得不提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 markdown

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)~固然你也能够扫描二维码打赏并直接包养帅气的博主一枚。

相关文章
相关标签/搜索