rem:css3的一个相对长度单位。相对于html元素的font-size计算值的倍数。即1rem 等于一倍的html元素的font-size值。

一、@media+rem

1. @media

媒体查询, 可以针对不同的屏幕尺寸设置不同的样式,特别是如果你需要设置设计响应式的页面,@media 是非常有用的。当你重置浏览器大小的过程中,页面也会根据浏览器的宽度和高度重新渲染页面 

上述代码中,第一个@media screen and (min-width:350px)表示当移动设备的宽度大于350px的时候页面将使用花括号内的样式,即将html根元素的字号设置为342%。(max-width:350px,则表示设备宽度小于350px时将采用此样式)。上述css代码的作用可见就是在不同分辨率的设备上设置不同的html字体大小。

为什么要这样设置呢?因为这种适配方法用的是css3的rem来进行适配的,而前面讲了,rem是相对于html的字号来计算的,现在不同的设备上html的字号改变了,也就意味这1rem代表的px像素值不同了,也就达到了按比例在不同设备上适配同一个页面的效果了。

2. font-size值如何确定

举例说明:

@media screen and (min-width:375px){
    html{font-size:366.2%;}
}

屏幕宽度大于375px的会按照宽度375px来适配。设计同时平时给我们的设计稿一般是640px宽度或者750px宽度的,而我们上面的都是假定设计稿是640px宽来计算的,750px也是同理计算。现在:

  1. 屏幕宽度是375,设计稿宽度是640,ratio = 375/640=0.5859375;
  2. 我们要将设计稿上元素用css单位rem写下来,那么该如何转换,1rem应该等于稿子上多少px。
  3. 这里我们设定1rem = 100px ;可以设定其它值吗,当然可以,这里设置为100只是方便我们在写css的时候好计算,小数点直接左移两位就可以了。比如,设计稿上一个宽46px按钮,这样转换成rem直接就是0.46rem。
  4. 现在1rem代表设计稿上100px,那么又该是等于设备上最后真实的多少像素呢。就要用到前面的屏幕宽度和设计稿的宽度比 ratio,设计稿上100px代表了真实的设备100*ratio = 58.59375px。
  5. 换句话说 css中写的1rem等于设备58.59375px。又因为1rem等于1倍的html元素的font-size,所以这里的html元素的font-size最终应该设置成58.59375px。可为什么上述代码中用的是百分比呢?因为一般浏览器中html元素的默认字号都是16px,但是当用户放大或者缩小浏览器字号设置时,就不会是16px了,所以我们将html的font-size还是设置成百分比更好,即 58.59375/16= 366.2109375%,也就是上面例子中的366.2%了。

其它的屏幕上也是同此道理计算出html的font-size值的。

3. viewport

@media + rem适配移动端还有一个不可少的条件就是要在head标签中写入一个meta标签。

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1, minimum-scale=1">

此标签的作用是让layout viewport = visual viewport,用户也不可缩放页面。

二、vw,vh

1. 什么是视口?

视口单位中的“视口”,桌面端指的是浏览器的可视区域;移动端指的就是Viewport中的Layout Viewport。注意移动端有三个视口:

  • layout viewport(布局视口):在PC端上,布局视口等于浏览器窗口的宽度。而在移动端上,由于要使为PC端浏览器设计的网站能够完全显示在移动端的小屏幕里,此时的布局视口会远大于移动设备的屏幕,就会出现滚动条。js获取布局视口:document.documentElement.clientWidth | document.body.clientWidth
  • visual viewport(视觉视口):用户正在看到的网页的区域。用户可以通过缩放来查看网站的内容。如果用户缩小网站,我们看到的网站区域将变大,此时视觉视口也变大了,同理,用户放大网站,我们能看到的网站区域将缩小,此时视觉视口也变小了。不管用户如何缩放,都不会影响到布局视口的宽度。js获取视觉视口:window.innerWidth
  • ideal viewport(理想视口):布局视口的一个理想尺寸,只有当布局视口的尺寸等于设备屏幕的尺寸时,才是理想视口。js获取理想视口:window.screen.width
  • 注意:移动端页面缩放时,布局视口不变,视觉视口缩小(可见区域变小);PC端页面放大时,布局视口缩小,视觉视口缩小(可见区域变小);

2. 视口单位

根据CSS3规范,视口单位主要包括以下4个:

  1. vw:1vw等于视口宽度的1%。
  2. vh:1vh等于视口高度的1%。
  3. vmin:选取vw和vh中最小的那个。
  4. vmax:选取vw和vh中最大的那个。

三、手机淘宝 flexible.js

这里还没弄懂,所以就直接抄过来了

flexible.js也是rem适配的,它是将设备分成10份,1rem等于1/10。分析其中部分代码:

var devicePixelRatio = win.devicePixelRatio;

        dpr = devicePixelRatio || 1;
        if (isIPhone) {

            // iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案
            if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {
                dpr = 3;
            } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){
                dpr = 2;
            } else {
                dpr = 1;
            }
        } else {
            // 其他设备下,仍旧使用1倍的方案
            dpr = 1;
        }
        scale = 1 / dpr;
        
       ......
       .......
        
       metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');

win.devicePixelRatio(简称dpr),即设备像素比

上述代码当dpr(设备物理像素和设备独立像素比)为3时候,页面缩入1/3,dpr为2时,页面绽放2/1。

function refreshRem(){
        var width = docEl.getBoundingClientRect().width;
        if (width / dpr > 750) {
            width = 750 * dpr;
        }
        var rem = width / 10;
        docEl.style.fontSize = rem + 'px';
        flexible.rem = win.rem = rem;
    }

上述代码将1rem设置成了设备真实宽度的1/10,因此html根元素的fontSize也就是设备真实宽度的1/10,假如设计老铁们给的漂亮稿子是750px宽的,写scss时1rem也就应该等于75px,那边我么的scss文件可以这样写:

@function px2rem($px, $base: 75) {
    @return ($px / $base) * 1rem;
}
/*
稿子上量得某按钮宽60px,高20px
*/
.btn{
    width:px2rem(60);
    height:px2rem(20);
}

参考资料

https://www.jianshu.com/p/7c5fdf90c0ef