在做移动端适配的时候,很多人第一反应就是使用 rem ,通过动态设置 html 上的 font-size 来进行页面的自适应,基本原理就是 rem 表示的是 root em ,页面中所有的值都是基于html上的 font-size ,相对的进行对应的变化
尤其是智能手机出现之后,我们没有办法在去固定我们的设备宽高,需要考虑 响应式 设计,根据浏览器窗口大小有不同的布局方式
css 中的单位
绝对单位
单位分为绝对单位和相对单位,其中绝对单位有 px、mm、cm、in、pt、pc 这些都可以相互转换
1in = 25.4mm = 2.54cm = 6pc = 72pt = 96px
当然我们还需要知道的是,css 虽然是一个绝对单位,但是它并不等于显示器的像素,需要通过 dpr 进行换算
最常见的相对单位是 em
和 rem
em
1em 表示的是当前元素的字号,可以看到 1em 是 16px,因为当前元素的 font-size 是 16px,浏览器会根据相对单位 em 计算出绝对单位 px,所以当你改变了这个元素的 font-size,其对应的 padding 也会随之变化,设置 padding、height、width、border-radius 这些属性的时候,使用 em 很方便,会动态根据 font-size 变化
那既然元素的 em 是根据当前元素的 font-size 来的,那给当前元素设置 font-size 使用 em ,那对应的值是什么呢?
可以看到,目前 font-size 变成了 32px ,为了得到 font-size 的值,需要参考继承的字号。这个时候如果设置了 padding 的值也是 2em ,虽然 font-size 和 padding 都是 2em ,但是它们的值是不一样的,padding 的大小为 64px ,font-size 先取到,然后根据 font-size 计算出padding
这里增加了计算的复杂性,所以一般font-size我们给固定的值就好,否则就会多层嵌套导致最终的结果不符合预期,所以如果不小心使用 em ,会让 em 很难按照我我们预想的来
所以我们有更好用的 rem
rem
在 html 文档中,根节点是所有其它元素的祖先,:root 表示根节点的伪类选择器,可以用来选中 html ,html 类型选择器和 :root 伪类选择器优先级是有区别的
rem 是 root em 的缩写,rem 不是相对于当前元素,而是相对于根元素,所以,不论什么位置,使用 rem 单位都是相对于根元素的 font-size
实际使用的选择性
既然 rem 这么好用,并且不存在 em 那么复杂的计算逻辑,是不是在项目中我们都用 rem 就好了呢?当然实际在项目中想必大家都是 rem 梭哈,这里我总结了一些适用场景
rem 一般情况下就是用来设置 font-size ,px 设置边框,em 设置绝大部分属性,比如padding margin border-radio 等等,这样统一的字号标准,让页面不论是缩放还是适配都游刃有余,所以当你拿捏不准使用什么方式来设置一些元素的时候,就按照上述的来,一般是没有什么问题的
使用 js 设置根元素 rem
自从有了 rem 这个便捷的相对单位,我们就有了一些奇怪的操作,比如用 js 设置根元素大小这个操作,就是将网页的根元素字号根据屏幕的大小动态设置为一个固定值,然后在页面中根据 ui 给出的图,换算成 rem 值,进行各种适配
甚至衍生出了一些 px 转换成 rem 的插件,当然这些做确实有些方便,但是不可否认的是它也有一定的问题
- 当屏幕小的时候,font-size 的大小会变成 10px ,但是我们好多系统最小字也就是 12px ,10px 展示有问题,导致我们需要给所有的元素上设置 至少为 1.2rem 才能保证显示正常
- 当屏幕过大的时候,比如移动端转到 pc 端,页面的根元素 font-size 又会变的很大,感官上根本不能用
实际应用
用以上所学,我们创建一个标题带段落的说明
代码语言:javascript复制<style>
:root{
font-size: 0.875em;
}
.container{
padding: 1em;
border-radius: .5em;
border: 1px solid #000;
}
h1{
margin-top: 0;
font-size: 1rem;
font-weight: bold;
}
p{
font-size: .8rem;
}
</style>
<body>
<div class="container">
<h1>FE情报局</h1>
<p>哈喽大家好,这里是FE情报局,我是局长,今天这篇文章深入理解的话,会学到如何使用现代 css 的布局方案,为我们提供一个响应式的布局,能够让我们不论是在页面缩放,还是不同的屏幕之间,都有良好的用户体验,当然根元素默认字号 14px</p>
</div>
</body>
这确实是会增加我们一些工作量,因为你需要思考什么时候使用 em ,什么时候使用 rem 以及 px 之间相互切换,但是好处也是很明显的
如果你想要将当前的内容做一个响应式
只需要这样
代码语言:javascript复制@media (min-width: 800px){
:root{
font-size: 1em
}
}
@media (min-width: 1200px){
:root{
font-size: 1.2em
}
}
随着屏幕的变化,字号逐渐增加,即便是对一个组件进行不同的自适应,你只需要更改对应组件的 font-size 即可
当然 css 中相对单位还有常见的内容
视口相对单位
- vh: 视口高度的1/100
- vw: 视口宽度的1/100
- vmin: 视口宽度或者高度中较小的一方1/100
- vmax: 视口宽度或者高度中较大的一方1/100
50vh 也就是视口高度的一半
刚才我们使用媒体查询定义了根元素 font-size ,当页面宽度变化到指定像素的时候会突然变成我们设置的内容,现在既然有了 vw ,是不是可以使用 vw 进行设置,视口改变时,元素自然过渡
实践一下
代码语言:javascript复制:root{
font-size: 2vw
}
这样在小屏幕上因为有最小字号限制,所以能够展示最小 12px 的字,但是屏幕一旦变大,导致字号也跟着变大,变小虽然字能看,但是边距会随之减小到很小的程度
有没有什么办法呢?
calc
calc 大家基本都用过,它可以对两个以及以上的值进行基本运算,比如calc(1em 10px)
,支持加减乘除
对于根节点,为了保证最小值,我们可以这样
代码语言:javascript复制:root{
font-size: calc(0.5em 1vw)
}
这样能保证最小值,也不至于屏幕大了字号过大,做了一个较好的适配
总结
这就是使用现代 css 的是配置方式
- 更多的使用相对单位来设置一些属性
- rem 设置字号,em 设置额外内容,px 设置边框
- 使用 calc vw 也能做好一般自适应