likes
comments
collection
share

移动端响应式布局技巧

作者站长头像
站长
· 阅读数 21

设备像素、设备独立像素、CSS 像素、PPI、devicePixelRatio

设备像素(物理像素 / 像素分辨率)

  • 显示器的最小物理单位(对于一个显示器来说是固定的)
  • 以手机屏幕为例,iphonex 像素分辨率为 1125x2436,是指屏幕横向能显示 1125 个物理像素点,纵向能显示 2436 个物理像素点。
  • 通常说的 4K 显示屏指的是 4096x2160

设备独立像素 (dips)

  • 比如我们偶尔会说“电脑屏幕在 2560x1600 分辨率下不适合玩游戏,我们把它调为 1440x900", 这里的“分辨率”(非严谨说法)指的就是设备独立像素。
  • 可在控制台通过 window screen.width/ window.screen.height 查看。
  • 另外,平时我们所说的 iphoneX 的逻辑分辨率 375x812 指的就是设备独立像素。chrome 检查元素模拟调试手机设备时显示如 375x667 和 320x480 都是设备独立像素。
  • 一个设备独立像素可能包含多个物理像素,包含的越多,显示越清晰

CSS 像素

  • 在页面不缩放的情况下,1px 的 CSS 像素 === 1 设备独立像素
  • 页面放大 200% 时,页面的设备独立像素依旧不变,放大的是 CSS 像素。但是此时 CSS 像素与设备独立像素的关系变化了,1px=== 4 独立像素(宽 x2,高 x2)

PPI

  • 指每英寸的物理像素数。
  • 以尺寸为 5.8 英寸 (屏幕对角线长度)、分辨率为 1125x2436 的 iphonex 为例:
  • ppi = Math.sqrt(11251125 + 24362436)/5.8,值为 463ppi。(屏幕对角线上的像素点 / 对角线的英寸数)

设备独立像素 (dips)

  • 像素比 window.devicePixelRatio
  • devicePixelRatio 指 的是物理像素和设备独立像素的比,即 1 独立像素由多少物理像素渲染。
  • dpr ( device pixel ratio) : 设备像素比,设备像素 / 设备独立像素,代表设备独立像素到设备像素的转换关系,在 JS 中可以通过 window.devicePixelRatio 获取;
  • window.devicePixelRatio= 物理像素 1 设备独立像素 (dips)。

DPR

widthDPR | heightDPR

viewport 缩放适配

  • layout viewport (布局视口)
  • visual viewport (视觉视口)
  • ideal viewport (理想视口) 和 dip (设备逻辑像素)

移动端响应式布局技巧

<meta name= "viewport" content= "width=device-width, initial-scale-1.0">
  • viewport 视口 - 可视区域窗口的大小
  • width=device -width 可视区域窗口的大小 = 设备大小
  • initial-scale=1.0 初始缩放比
  • user-scaleable :no 禁止用户进行手动缩放

注意手机适配 这段必须加上

媒体查询 @media

语法:@media 媒体类型逻辑操作符(媒体属性) { 样式代码}

   /* 小屏幕(平板,大于等于 768px) */
   @media (min-width: 768px) { }

   /* 中等屏幕(桌面显示器,大于等于 992px) */
   @media (min-width: 992px) { }

   /* 大屏幕(大桌面显示器,大于等于 1200px) */
   @media (min-width: 1200px) { }

css 常用的长度单位

单位:px、em、%、rem、vw

px

固定单位写死

em

  • 相对单位父元素的字体的大小
  • 1em = 16px 它的父元素 html 16px

%

相对于父元素的尺寸

rem

相对单位 root element font-size html{font-size:16px;}

  • 1rem = 16px ? =160px font-size:16px
  • 为了方便计算 10px 100px(建议) 1rem = 100px
/*
设计稿的宽度:designWidth
允许自适应的最大宽度(超过这个值屏幕元素不在自适应增大):maxWidth
页面顶部加上:<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no" >
这段js的传入两个参数:一个为设计稿实际宽度,一个为显示的最大宽度(允许的屏幕最大宽度,用来限制屏幕过大之后元素还会自适应增大的)
例如设计稿为750,最大宽度为600,则为(750,600),屏幕大于600之后就不会自适应变大了,也相当于在用@media属性时min-width只设置到了600,没有后面的屏幕尺寸,就不会再变化了
公式:1rem = 浏览器屏幕宽(width) * 100 / 设计稿宽(designWidth)
(750,750)含义1rem = clientWidth * 100 / 750
(750,2160)含义1rem = clientWidth * 100 / 750
clientWidth是动态获取的
后面的750和2160表示maxWidth,如果浏览器窗口(clientWidth)大于这个数值就将clientWidth设置成这个数值(maxWidth)。而width是根据屏幕变化动态获取的
*/
;(function (designWidth, maxWidth) {
    var doc = document,
        win = window,
        docEl = doc.documentElement,
        remStyle = document.createElement("style"),
        tid;

    function refreshRem() {
        var clientWidth = docEl.getBoundingClientRect().width;//获取document的宽度,浏览器屏幕宽度
        maxWidth = maxWidth || 540;//短路运算符,如果前面式子为false再执行后面,如果赋值了maxWidth那么maxWidth=maxWidth,否则没有赋值那么maxWidth为false,就会执行maxWidth=540
        clientWidth > maxWidth && (clientWidth = maxWidth);//短路运算符,如果前面式子true再执行后面
        var rem = clientWidth * 100 / designWidth;
        remStyle.innerHTML = 'html{font-size:' + rem + 'px;}';
    }

    if (docEl.firstElementChild) {
        docEl.firstElementChild.appendChild(remStyle);
    } else {
        var wrap = doc.createElement("div");
        wrap.appendChild(remStyle);
        doc.write(wrap.innerHTML);
        wrap = null;
    }
    refreshRem();
    //要等 wiewport 设置好后才能执行 refreshRem,不然 refreshRem 会执行2次;


    win.addEventListener("resize", function () {
        clearTimeout(tid); //防止执行两次
        tid = setTimeout(refreshRem, 300);
    }, false);

    /*
    浏览器后退的时候重新计算,为了查看页面是直接从服务器上载入还是从缓存中读取,你可以使用 PageTransitionEvent 对象的 persisted 属性来判断。
    如果页面从浏览器的缓存中读取该属性返回 ture,否则返回 false
    */
    win.addEventListener("pageshow", function (e) {
        if (e.persisted) {
            clearTimeout(tid);
            tid = setTimeout(refreshRem, 300);
        }
    }, false);

    /*
    为什么一般多是 html{font-size:62.5%;} 而不是 html{font-size:10px;}呢?
    因为有些浏览器默认的不是16px,或者用户修改了浏览器默认的字体大小(因浏览器分辨率大小,视力,习惯等因素)。
    如果我们将其设置为10px,一定会影响在这些浏览器上的效果,所以最好用绝大多数用户默认的16作为基数 * 62.5% 得到我们需要的10px。
    实际项目设置成 font-size: 62.5%可能会出现问题,因为chrome不支持小于12px的字体,计算小于12px的时候,会默认取12px去计算,导致chrome的em/rem计算不准确。
    针对这个现象,可以尝试设置html字体为100px,body 修正为16px,这样 0.1rem 就是 10px,而body的字体仍然是默认大小,不影响未设置大小的元素的默认字体的大小。
    */
    if (doc.readyState === "complete") {
        doc.body.style.fontSize = "16px";//页面元素默认16px,如果不设置将是自动为16px显示
    } else {
        doc.addEventListener("DOMContentLoaded", function (e) {
            doc.body.style.fontSize = "16px";
        }, false);
    }
})(750, 750);
html {
 font-size:100px;
}

@media screen and (max-width:320px){
    html {
        font-size: 42.667px;
    }
}

@media screen and (max-width:321px) and (max-width:375px)  {
    html {
        font-size: 48px;
    }
}

@media screen and (max-width:376px) and (max-width:393px)  {
    html {
        font-size: 52.4px;
    }
}

媒体查询的方式修改

vm

  • 相对单位 viewport width 把视口大小分为 100 等分
  • 1vw = 1/100*视口