写在前面
我们在前端切页面的时候经常会被要求适配各种比例的屏幕,那么我们该怎么做呢?
做一个PC端的网页,设计图是1920X1080的. 要在常见屏上显示正常(比例正确可) 1280X720 1366X768 1440X900 1920X1080
使用了以下几种方案
1.内容在一屏内显示的,采用了(内容框)上下左右居中的办法,里面的内容绝对于这个内容框定位.这样一来,在不同大小屏中,内容总是在中间,看起来较正常
2.长,宽,LEFT,TOP,RIGHT,BOTTOM都采用了REM,并且HTML的FONT-SIZE设置的是100PX一是觉得计算方便,二是如果设为10PX,谷歌会不兼容.此时BODY的FONT-SIZE设置为正常值,12PX.不然的话,其它的DOM都会继承HTML的100PX的FONT-SIZE,导致效果巨大.
3.当浏览器窗口变化时,内容的大小以及相对位置也会相应变化,这个依靠JS修改HTML的FONT-SIZE值实现.如下:
$(window).resize(function () // 绑定到窗口的这个事件中
{
var whdef = 100/1920;// 表示1920的设计图,使用100PX的默认值
var wH = window.innerHeight;// 当前窗口的高度
var wW = window.innerWidth;// 当前窗口的宽度
var rem = wW * whdef;// 以默认比例值乘以当前窗口宽度,得到该宽度下的相应FONT-SIZE值
$('html').css('font-size', rem + "px");
});
计算font-size的逻辑是:
当设计图是1920时,规定HTML的FONT-SIZE的值是100. 也就是,当浏览器窗口调整到1920PX时,1REM=100PX,如果要设定一个16PX(1920设计图时)的字体,那么REM设置值是0.16.
当窗口调整到非设计图的宽度如winWidth时,HTML的FONT-SIZE值是:(100/1920)*winWidth.也就是说,1920下FONT-SIZE是100px.那么winWidth下,按比例计算.
或者可以这样:窗口宽1920时,FONT-SIZE是100PX,那么winWidth时,相当于窗口变化为1920时的 (winWidth / 1920).根据比例公式,winWidth时的FONT-SIZE就是 (winWidth/1920)*100
winWidth / 1920 = FONT-SIZE(PX) / 100
100 / 1920 = FONT-SIZE(PX) / winWidth 这个公式容易理解
如果调整窗口大小,会发现HTML的FONT-SIZE值在变化,同时,使用REM设置的DOM也在变化.因为REM正是参考HTML的FONT-SIZE值来计算的.
2、手机上,平板电脑上,更要使用REM,由于手机上一般不会调整浏览器大小,
所以可以在页面载入时,设置一次即可
$(function(){
var whdef = 50/750;// 表示750的设计图,使用50PX的默认值
var wH = window.innerHeight;// 手机窗口的高度
var wW = window.innerWidth;// 手机窗口的宽度
var rem = wW * whdef;// 以默认比例值乘以当前窗口宽度,得到该宽度下的相应FONT-SIZE值
$('html').css('font-size', rem + "px");
})
- 如下的计算单位(像素)计算单位为1rem=75px;
!function(N,M){function L(){var a=I.getBoundingClientRect().width;a/F>540&&(a=540*F);var d=a/10;I.style.fontSize=d+"px",D.rem=N.rem=d}var K,J=N.document,I=J.documentElement,H=J.querySelector('meta[name="viewport"]'),G=J.querySelector('meta[name="flexible"]'),F=0,E=0,D=M.flexible||(M.flexible={});if(H){console.warn("将根据已有的meta标签来设置缩放比例");var C=H.getAttribute("content").match(/initial\-scale=([\d\.]+)/);C&&(E=parseFloat(C[1]),F=parseInt(1/E))}else{if(G){var B=G.getAttribute("content");if(B){var A=B.match(/initial\-dpr=([\d\.]+)/),z=B.match(/maximum\-dpr=([\d\.]+)/);A&&(F=parseFloat(A[1]),E=parseFloat((1/F).toFixed(2))),z&&(F=parseFloat(z[1]),E=parseFloat((1/F).toFixed(2)))}}}if(!F&&!E){var y=N.navigator.userAgent,x=(!!y.match(/android/gi),!!y.match(/iphone/gi)),w=x&&!!y.match(/OS 9_3/),v=N.devicePixelRatio;F=x&&!w?v>=3&&(!F||F>=3)?3:v>=2&&(!F||F>=2)?2:1:1,E=1/F}if(I.setAttribute("data-dpr",F),!H){if(H=J.createElement("meta"),H.setAttribute("name","viewport"),H.setAttribute("content","initial-scale="+E+", maximum-scale="+E+", minimum-scale="+E+", user-scalable=no"),I.firstElementChild){I.firstElementChild.appendChild(H)}else{var u=J.createElement("div");u.appendChild(H),J.write(u.innerHTML)}}N.addEventListener("resize",function(){clearTimeout(K),K=setTimeout(L,300)},!1),N.addEventListener("pageshow",function(b){b.persisted&&(clearTimeout(K),K=setTimeout(L,300))},!1),"complete"===J.readyState?J.body.style.fontSize=12*F+"px":J.addEventListener("DOMContentLoaded",function(){J.body.style.fontSize=12*F+"px"},!1),L(),D.dpr=N.dpr=F,D.refreshRem=L,D.rem2px=function(d){var c=parseFloat(d)*this.rem;return"string"==typeof d&&d.match(/rem$/)&&(c+="px"),c},D.px2rem=function(d){var c=parseFloat(d)/this.rem;return"string"==typeof d&&d.match(/px$/)&&(c+="rem"),c}}(window,window.lib||(window.lib={}));