使用rem/em实现字体自适应
本文主要讲解提升用户体验的其中一个技巧:字体自适应。
首先,我们要清楚在字体设置中比较常用的三个单位:px
,rem
,em
。
px
是一个大小单位,相当于 1 像素,这样写字体大小就是固定的,绝对值;rem
,em
两者都是比例单位,只是相对比的对象不同,相对值:em
是相对于父级的,父级字体设置 20px,子级设置 0.5em,即 20*0.5=10px,rem
是相对于根的,根设置字体 30px,我设置 0.5rem,即 30*0.5=15px。
使用em
和rem
单位可以让设计更加灵活,能够控制元素整体放大缩小,而不是固定大小。可以使用这种灵活性,在开发期间能更加快速灵活的调整,允许浏览器用户调整浏览器大小以达到最佳体验。em 和 rem 单位提供的这种灵活性和工作方式都很相似。
那么,何时使用 em 值,何时应使用 rem 值呢?
有一个比较普遍的误解,认为em
单位是相对于父元素的字体大小。事实上,根据 W3C 标准,它们是相对于使用em
单位的元素字体大小。父元素的字体大小可以影响em
值,但这种情况的发生,纯粹是因为继承。
使用em
单位存在继承的时候,情况会变得比较棘手,因为每个元素将自动继承其父元素的字体大小。
继承效果只能被明确的字体单位覆盖,比如px
,vw
使用em
单位的元素字体大小根据它们来定。但该元素可能继承其父元素的字体大小,而父元素又继承其父元素的字体大小,等等。因此,以em
为单位的元素字体大小可能会受到其任何父元素的字体大小影响。
em 继承的例子
如果根元素字体大小为 16px(通常是默认值)一个子元素div
里面padding
值为 1.5em,该div
将从根元素继承字体大小 16px。因此padding
会翻译成 24px,即 1.5 x 16=24。
如果多加一个 div 来包裹原先的 div,然后设置其字体大小为 1.25em 呢?
包裹的 div 继承根元素字体大小 16px,并乘以它自己的 1.25em 的字体大小。这将设置包裹 div 字体大小为 20px,即 1.25 x 16=20。现在原始的 div 不再直接从根元素继承,而是从其新的父元素继承字体大小为 20px 1.5em 其 padding 值现在等于 30px,即 1.5 x 20=30。
这个继承效应可以更复杂,如果向原始的 div 添加 em 字体单位,比方说 1.2em。Div 从其父级继承 20px 字体大小,然后,乘以它自己的 1.2em 设置,给它 24px,即 1.2×20=24 新字体大小。div 上的 1.5em padding 现在将再次改变大小,用新的字体大小,36px,即 1.5×24=36。
最后,为了进一步说明哪个 em 单位是相对于他们最终获得(不是父元素)的字体大小,让我们来看看设置 padding 1.5em 如果我们显式设置 div 使用 14px 值,不继承字体大小会发生什么。现在,我们的 padding 为 21px,即 1.5 x 14=21 已经变小了。它不受父元素的字体大小。由于存在着这些隐患,你可以看到为什么必须知道如何正确管理使用 em 单位。
根 html 元素将继承浏览器中设置的字体大小,除非显式设置固定值去覆盖。所以 html 元素的字体大小虽然是直接确定 rem 值,但字体大小可能首先来自浏览器设置。因此浏览器的字体大小设置可以影响每个使用 rem 单元以及每个通过 em 单位继承的值。
注:在没有设置 HTML 字体大小时,浏览器设置起作用。
除非重写,否则它将继承浏览器默认设置的字体大小。例如,让我们把网站的 html 元素没有设置 font-size 值。如果用户让他们的浏览器默认字体大小为 16px,那么根元素字体大小将为 16px。
假如在项目开发中,我们需要设置一个全局的自适应字体,也就是根的字体大小,这里将 html 设成根,那我们来看看详细步骤吧。
步骤 1:
在 vue 的 App.vue 页面设置全局字体大小
mounted() { let width=$("body").width(); if(width>=1200){ let fontsize=width/1920*40;//fontsize 为当前屏幕的基数字体,相对于设计稿计算得到的。 $("html").css("font-size",`${fontsize}px`) }//当加载页面的时候设置生效 window.onresize = () => {//当页面尺寸改变的时候生效 return (() => { let width=$("body").width(); if(width>=1200){ let fontsize=width/1920*40; $("html").css("font-size",`${fontsize}px`) } })() } }
由于页面可视部分大小是 1200px,所以这边设置了范围 1200px 以上。
步骤 2:
根据基数字体设置相应字体大小rem
为单位,比如:基数为 40px,20px 相对于 40px 就是 0.5rem,只要你将 20px 地方改成 0.5rem 即可。
如果你不想计算可以采用calc()
函数:
font-size:calc(20 * 1rem / 40);
calc()
是 css 中动态设置长宽高,间距等等。需要注意的是运算符两边要有空格,不然不会生效。
关于 calc()如果大家还有不懂得可以看我之前的文章《css3 calc()属性介绍以及自适应布局使用方法》《CSS calc()的完整指南》
总结:
这样页面上的字体就可以随着你的屏幕大小设置成相应字体大小,不会再有按照设计稿设置,字体太大的问题了。另外,在编写的时候,既然字体px
可以使用这个,那间距等等也可以动态设置,称之为活性间距,屏幕越小,字体越小,间距越小。这样子编写,基本可以是设计稿参数的等比例缩放,在视觉上可以更舒服。
实际应用
使用 em 单位
根据某个元素的字体大小做缩放而不是根元素的字体大小。一般来说,你需要使用em
单位的唯一原因是缩放没有默认字体大小的元素。根据我们上面的例子,设计组件比如按钮,菜单和标题可能会有自己明确的字体大小。当你修改字体大小的时候,你希望整个组件都适当缩放。通用属性这一准则将适用于在非默认字体大小的元素上的padding
、margin
、width
、height
和line-height
等值。我建议,当你使用em
单位,他们使用的元素的字体大小应设置对rem
单位,以保留的可扩展性,但避免继承混淆。
通常不使用 em 单位控制字体大小
我们经常会看到使用em
作为字体大小单位,特别是标题,但我认为如果使用rem
将更具可扩展性。标题经常使用em
单位的原因是他们相比px
单位,在相对常规文本大小方面更出色。然而rem
单位同样也可以实现这一目标。
如果 html 元素上任何字体大小调整,标题大小仍会缩放。少部分情况下,我们不想我们的字体大小根据根元素做调整,只有几个例外的情况。我们可以想到的例子是一个使用em
字体大小的下拉菜单,我们有第二个级别的菜单项文本大小取决于第一级字体大小。
另一个例子可能是用在按钮里面的字体图标,字体图标的大小跟按钮的文本大小有关。然而,大多数 web 设计中的元素往往不会有这种类型的要求,所以一般使用rem
单位的字体大小,em
单位只在特殊的情况下使用。
使用 rem 单位
不需要em
单位,并且根据浏览器的字体大小设置缩放的任何尺寸。这几乎在一个标准的设计中占据了一切,包括height
,width
,padding
,margin
,border
,font-size
,shadows
,几乎包括你布局的每部分。简单地说,一切可扩展都应该使用 rem 单位。
小贴士
创建布局时,往往要以像素为单位更方便,但部署时应使用rem
单位。你可以使用预处理比如Stylus/Sass/Less
,来自动转换单位或PostCSS
之类的插件。或者,可以使用PXtoEM
手动做转换。
始终使用 rem 单位做媒体查询
特别注意,当使用rem
单位创建统一可扩展的设计,媒体查询也应该是rem
单位。这将确保,无论用户浏览器的字体大小,媒体查询会对它作出反应和调整你的布局。例如,如果用户缩放文本非常高,布局可能需要从两列到单个列调整,因为它可能会在较小的移动设备上显示。如果断点在固定的像素宽度,只有不同的视口的大小可以触发它们。但是基于rem
的断点他们将响应不同的字体大小。
不要使用 em 或 rem
多列布局
布局中的列宽通常应该是%
,因此他们可以流畅适应无法预知大小的视区。然而单一列一般仍然应使用rem
值来设置最大宽度。例如:
.container { width: 100%; max-width: 75rem; }
这保持列的灵活,可扩展。又能防止变得太宽了。
当元素是严格不可缩放的时候
在一个典型的 web 设计过程中,不会存在很多部分是你不能使用伸缩性设计的布局。不过偶尔你会遇到真的需要使用显式的固定的值,以防止缩放的元素。采用固定的尺寸值的前提应该是,如果被缩放的话,它的结构会被打破。这真的不常出现,所以你想拿出那些px
单位之前,问问自己是否使用它们是绝对必要的。
总结
rem
和em
单位是由浏览器基于你的设计中的字体大小计算得到的像素值。em
单位基于使用他们的元素的字体大小。rem
单位基于 html 元素的字体大小。em
单位可能受任何继承的父元素字体大小影响。rem
单位可以从浏览器字体设置中继承字体大小。- 使用
em
单位应根据组件的字体大小而不是根元素的字体大小。 - 在不需要使用
em
单位,并且需要根据浏览器的字体大小设置缩放的情况下使用rem
。 - 使用
rem
单位,除非你确定你需要em
单位,包括字体大小。 - 媒体查询中使用
rem
单位 - 不要在多列布局中使用
em
或rem
改用%
。 - 不要使用
em
或rem
,如果缩放会不可避免地导致要打破布局元素。
码云笔记 » 使用rem/em实现字体自适应