移动端适配的五种方案 em rem vw/vh 百分比 媒体查询

移动端适配的几种方案:

  • rem方案
  • vw/vh方案
  • rem+vw方案
  • 百分比
  • 基于媒体查询的响应式设计

前言

先来认识一下em:

em是相对长度单位。相对于当前对象内文本的字体尺寸。如当前对行内文本的字体尺寸未被人为设置,则相对于浏览器的默认字体尺寸。

em特点:em的值并不是固定的;em会继承父级元素的字体大小。

注意:任意浏览器的默认字体高都是16px。所有未经调整的浏览器都符合: 1em=16px。那么12px=0.75em,10px=0.625em。为了简化font-size的换算,需要在css中的body选择器中声明Font-size=62.5%,这就使em值变为 16px*62.5%=10px, 这样12px=1.2em, 10px=1em, 也就是说只需要将你的原来的px数值除以10,然后换上em作为单位就行了。

所以我们在写CSS的时候,需要注意几点:

  1. body选择器中声明Font-size=62.5%;
  2. 将你的原来的px数值除以10,然后换上em作为单位;
  3. 重新计算那些被放大的字体的em数值。避免字体大小的重复声明。
    也就是避免1.2 * 1.2= 1.44的现象。比如说你在#content中声明了字体大小为1.2em,那么在声明p的字体大小时就只能是1em,而不是1.2em, 因为此em非彼em,它因继承#content的字体高而变为了1em=12px。

接下来,我们来看移动端适配的几种方案:

1. rem方案

rem是CSS3新增的一个相对单位(root em,根em)。这个单位与em的区别在于rem相对的是HTML根元素。这个单位可谓集相对大小和绝对大小的优点于一身,通过它既可以做到只修改根元素就成比例地调整所有字体大小,又可以避免字体大小逐层复合的连锁反应。目前,除了IE8及更早版本外,所有浏览器均已支持rem。对于不支持它的浏览器,应对方法也很简单,就是多写一个绝对单位的声明。这些浏览器会忽略用rem设定的字体大小。下面就是一个例子:

p {
     font-size:14px; font-size:.875rem;}

rem方案的原理:
rem是相对长度单位,相对html元素(文档根元素doucment.documentElement)计算值的倍数。根据屏幕宽度设置html标签的font-size,在布局时使用rem单位,达到自适应的目的,是弹性布局的一种实现方式。

当页面全屏显示时,设置 html 默认字体大小为100px,则子元素中1rem就等于100px,相当于设计稿中的1px等于0.01rem,使用的时候设计稿中的尺寸直接除以100,100px就是1rem,10px就是0.1rem。
移动端适配的五种方案 em rem vw/vh 百分比 媒体查询_第1张图片
当页面缩放后,需要重新计算html的字体大小
移动端适配的五种方案 em rem vw/vh 百分比 媒体查询_第2张图片
PC端使用相关Js代码如下:

export default class Rem {
     
    static init(){
     
    	//设置默认尺寸
        Rem.defaultStyle();
        //缩放后,重新计算html字体大小
        Rem.resizeHandler();
        //监听浏览器缩放事件
        window.addEventListener("resize", Rem.resizeHandler);
    }
    //计算html字体大小
    static resizeHandler() {
     
        let contW = Math.floor(document.documentElement.clientWidth);
        let fontS = (contW / screen.width) * 100;
        document.documentElement.style.fontSize = fontS + "px";
    }
    //设置html默认字体为100px body字体为16px
    static defaultStyle(){
     
        document.documentElement.style.fontSize = "100px";
        document.body.style.fontSize = "16px";
    }
    //px 转换成 rem
    static getRem(size) {
     
        var fontSize = parseFloat(getComputedStyle(document.documentElement).fontSize);
        return size / fontSize;
    }
}

移动端使用相关JS代码如下(设计图尺寸以750为例):

(function(w){
     
    var docEl=w.document.documentElement;
    var timer;

    function refersh(){
     
      var width=docEl.getBoundingClientRect().width;
      if(width>750) width=750;
      var rem = width/7.5;
      docEl.style.fontSize=rem+"px";
    }

    w.addEventListener("resize",function(){
     
      timer && clearTimeout(timer);
      timer=setTimeout(refersh,400)
    })

    w.addEventListener('pageshow', function () {
     
      timer && clearTimeout(timer);
      timer = setTimeout(refersh, 400)
    })

  })(window)

使用rem方案的优点

  • 自适应效果好;
  • 兼容性好,除了IE8及更早版本外,所有浏览器均已支持rem。

缺点

  • 不是纯css移动适配方案,需要引入js脚本,监听浏览器窗口缩放行为动态改变根元素的字体大小。css样式和js代码有一定耦合性,并且必须将改变 font-size 的代码放在css样式之前。
  • 小数像素问题,浏览器渲染最小的单位是像素,元素根据屏幕宽度自适应,通过 rem 计算后可能会出现小数像素,浏览器会对这部分小数四舍五入,按照整数渲染。浏览器在渲染时所做的摄入处理只是应用在元素的尺寸渲染上,其真实占据的空间依旧是原始大小。也就是说如果一个元素尺寸是 0.625px,那么其渲染尺寸应该是 1px,空出的 0.375px 空间由其临近的元素填充;同样道理,如果一个元素尺寸是 0.375px,其渲染尺寸就应该是0,但是其会占据临近元素 0.375px的空间。会导致:缩放到低于1px的元素时隐时现(解决办法:指定最小转换像素,对于比较小的像素,不转换为 rem 或 vw);两个同样宽度的元素因为各自周围的元素宽度不同,导致两元素相差1px;宽高相同的正方形,长宽不等了;border-radius: 50% 画的圆不圆。
  • Android 浏览器下 line-height 垂直居中偏离的问题。常用的垂直居中方式就是使用line-height,这种方法在Android设备下并不能完全居中。
  • cursor: pointer 元素点击背景变色的问题,对添加了cursor:pointer属性的元素,在移动端点击时,背景会高亮。为元素添加tag-highlight-color:transparent属性可以隐藏背景高亮。

2. vw/vh方案

视口是浏览器中用于呈现网页的区域,也就是用户所能看到的页面区域。

  • 1vw,等于视口宽度的1%;
  • 1vh,等于视口高度的1%;
  • vmin,选取vw和vh中最小的那个值;
  • vmax,选取vw和vh中最大的那个值;

使用的时候,所有的px单位除以100,也可以通过css预处理器将px单位转换为vw,点击查看在 vue-cli中怎样使用postcss-px-to-viewport 将px转换成vw

以1080px设计稿为基准,转化的计算为

// 以1080px作为设计稿基准
$vw_base: 1080
@function vw($px) {
     
    @return($px / 1080) * 100vw
}

vw/wh方案的优点:

  • 纯css移动端适配方案,不存在脚本依赖的问题;
  • 根据视口宽度的百分比来定义元素宽度,计算方便;

缺点:

  • 存在兼容问题,只在移动端 iOS 8 以上以及 Android 4.4 以上获得支持;

3. rem+vw方案

vw/vh方案计算方便,能够很好地实现适配效果,但是存在一定的兼容问题,将vw/vh方案和rem方案相结合,设置html元素的font-size单位为vw,然后在布局中直接使用rem单位。

例如,设计稿的宽度为750px,则1vw=7.5px,为了方便计算,我们将html元素的font-size大小设置为100px,也就是13.333vw=100px。

html{
     font-size:13.333vw}

设置html{font-size:13.333vw},在样式代码中1rem=13.333vw=100px,即1rem等于设计稿上的100px,使用的时候除以100,直接小数点向左移动2位,1rem等于100px,那么10px就是0.1rem。

这样的好处是不需要使用postcss-pxtorem 插件来转换单位,如果使用插件,想写px的地方还需要设置propList或者selectorBlackList。使用这种方案的话就不存在这个问题了,想用相对单位就写rem,想用绝对单位就写px,不需要其他的设置。

这种方案的优点:从rem方案过渡到vw,只是需要通过改变根元素字体大小的计算方式,将单位改成vw,不需要其他处理。

这种方案的缺点:,这种方案只对手机的兼容性很好,ipad或者是pc端的效果就不是很好。因为根节点的字体单位使用的是vw,当设备的宽度越来越大时,使用rem做单位的元素也会越来越大,以至于在ipad或者是pc上展示的效果会很差。

解决方案:当屏幕过大的时候,我们可以使用媒体查询来限制根元素的字体大小,实现对页面的最大最小宽度限制。

例如,在样式中加上这句代码,在pc上效果也很不错了。

@media (min-width: 560px) {
     
  html {
     
    font-size: 54px;
  }
}

4. 百分比方案

相对于父元素的宽度,使用百分比的单位来定义子元素的宽度。子元素的高度使用px来定义,使用max-width/min-width 控制子元素的最大最小尺寸。

属性 参考对象
height/width 相对于子元素的直接父元素
top/bottom/left/right 相对于有定位属性的父元素
padding/margin 相对于直接父元素
border-radius 相对于自身

这种方式的优点是原理简单,不存在兼容性问题。

缺点是

  • 字体大小无法随着屏幕大小变化而改变;
  • 设置盒模型的不同属性时,其百分比设置的参考元素不唯一,容易使布局问题变得复杂。

5. 基于媒体查询的响应式设计

基于媒体查询的响应式设计,响应式设计,使得一个网站可以同时适配多种设备和多个屏幕,让网站的布局和功能随用户的使用环境(屏幕大小、输出方式、设备/浏览器)而变化,使其视觉合理,交互方式符合习惯。

css3中的@media,通过给不同分辨率的设备编写不同的样式规则实现响应式布局,使一个网站可以在不同尺寸的屏幕下显示不同的布局效果。主要用来解决不同设置不同分辨率之间的兼容问题,一般是指pc、平板、手机设备之间较大的分辨率差异。实现上不局限于具体的方案,通常是结合流式布局和弹性布局方案。比如给小屏幕手机设置@2x图,给大屏手机设置@3x图。

@media only screen and (min-width: 375px){
     
    /*样式1*/
}
@media only screen and (min-width: 750){
     
    /*样式2*/
}

这种方案的优点

  • 能够使网页在不同设备、不同分辨率的屏幕上呈现合理布局,不单单是样式伸缩变换。

缺点

  • 如果要匹配足够多的设备与屏幕,一个web页面需要多个设计方案,工作量比较大。
  • 通过媒体查询技术需要设置一定量的断点,到达某个断点前后的页面发生突兀变化,用户体验不太友好。

总结

对于上述的各种移动端web页面自适应方案来说,都存在着一些优势和不足。对于国内的一些互联网站,通过查看网页源代码发现,它可能不是某一种方案的单独使用,而是几种方案的结合。一个页面上,元素的宽度设置上有百分比,也有rem,字体的样式中有rem,有em,也有固定大小的px;在屏幕宽度过大时不再缩放,也会用到媒体查询,并且响应式设计更多地可能是针对不同设备间的自适应。对于移动端web页面的自适应方案来说,现在用的比较多的是rem,逐渐向vw/vh发展,而rem+vw/vh则是作为vw/vh向后兼容的一种过渡。

参考:https://www.jianshu.com/p/2c33921d5a68

你可能感兴趣的:(html5,css3,html,html5)