zoukankan      html  css  js  c++  java
  • 移动端布局适配方案

    一.前提知识

    移动端的屏幕尺寸有多种,其中要知道几个知识

    物理像素:即设计稿的尺寸

    逻辑像素:实体机器的真正像素

    下面是我们经常适配的屏幕尺寸

    一.rem+@media布局

    rem是以根元素字体大小作为参照的布局方式

    //以750px设计稿为例,物理像素是375px.设置div宽度为整个容器宽度一半
    html{font-size:12px}
    div{375/2/12 rem}

     常用的布局方式是:rem+@media

    @media可以针对不同的屏幕尺寸作出不同的样式设置,也就可以定义不同的font-size

    移动端布局时,假设设计稿尺寸是750,但是要适应多个屏幕尺寸,比如375,414,320,360.为了保证屏幕尺寸改变时页面不变,我们需要保证比例不变,也就是:

     
    750设计稿的字体是100px,其他设备屏幕宽度比上字体的比例应该一样,也就是:
    750/100=屏幕a/屏幕字体大小
    屏幕字体大小=屏幕a/750*100
    750设备+750设计稿:100px的根元素字体大小= (750 / 750 ) * 100 = 1rem
    320设备+750设计稿:根元素字体大小= (320 / 750 ) * 100  = 42.67px
    360设备+750设计稿:根元素字体大小= (360 / 750 ) * 100 = 48
    375设备+750设计稿:根元素字体大小= (375 / 750 ) * 100 = 50
    411设备+750设计稿:根元素字体大小= (411 / 750 ) * 100 = 55.2
    414设备+750设计稿:根元素字体大小= (414 / 750 ) * 100 = 50
    640设备+750设计稿:根元素字体大小= (640 / 750 ) * 100 = 85.33
    1242设备+750设计稿:根元素字体大小= (1242 / 750 ) * 100 = 165.6
    通过@media screen判断屏幕尺寸,不同屏幕尺寸设置不同的根元素字体大小
    @media screen and (min-320px){
                html,body{
                    font-size:42.67px
                }
            }
    
            @media screen and (min-375px){
                html,body{
                    font-size:50px
                }
            }
    
            @media screen and (min-414px){
                html,body{
                    font-size:55.2px
                }
            }
    
            @media screen and (min-360px){
                html,body{
                    font-size:48px
                }
            }
    
            @media screen and (min-411px){
                html,body{
                    font-size:54.8px
                }
            }
    
            @media screen and (min-640px){
                html,body{
                    font-size:85.33px
                }
            }
            @media screen and (min-750px){
                html,body{
                    font-size:100px
                }
            }
    
    
            @media screen and (min-1242px){
                html,body{
                    font-size:165.6px
                }
            }

    设置完以上这些后,不同的屏幕会设置不同的font-size.

    vscode安装cssrem,配置后可以在css页面写px时会自动将px转化为rem

    配置如图

    这里设置根目录的font-size

      

    二.rem+vw布局

    • vw1vw 等于 window.innerWidth 1%,相当于是说vw把屏幕宽度分为了100份,100vw=屏幕宽度
    • vh1vh 等于 window.innerHeight 1%

    vw是动态改变的,而rem做移动端布局正好需要动态改变.所以我们可以把根元素字体大小设置vw.

    以750设计稿举例:

    我们通常要把根目录字体大小设置为100px,

    100vw=375px;

    100px=(100/375)*100=26.6667vw.

    所以把根目录字体大小设置为26.6667vw.

    因为vm是相对于屏幕的,26vw在不同屏幕宽度下对应的实际大小不同,就完成了大小随屏幕自适应(750设计稿只是标准!!!)

    在具体使用时,比如18px大小的字体,我们结合rem+vw,把18px大小写为0.18rem;0.18rem在不同屏幕宽度下就会表现出不同的大小

    四.Flexible布局

    使用Flexible实现手淘H5页面的终端适配rem自适应布局-移动端自适应必备

    用法:1,删除meta标签

           2,元素尺寸转化为rem计算方法:元素尺寸/100 rem,flexbox文件内部会有一系列判断和转换,比如设置宽度为50px,div{50/100 rem}

           3,特殊的是375设计稿,元素尺寸转化为rem计算方法:元素尺寸*2/100 rem

          4,在head中放入flexible,这样能兼容华为手机

    <script>
            (function (win, lib) {
                var doc = win.document;
                var docEl = doc.documentElement;
                var metaEl = doc.querySelector('meta[name="viewport"]');
                var flexibleEl = doc.querySelector('meta[name="flexible"]');
                var dpr = 0;
                var scale = 0;
                var tid;
                var flexible = lib.flexible || (lib.flexible = {});
    
                if (metaEl) {
                    //        console.warn('将根据已有的meta标签来设置缩放比例');
                    var match = metaEl.getAttribute('content').match(/initial-scale=([d.]+)/);
                    if (match) {
                        scale = parseFloat(match[1]);
                        dpr = parseInt(1 / scale);
                    }
                } else if (flexibleEl) {
                    var content = flexibleEl.getAttribute('content');
                    if (content) {
                        var initialDpr = content.match(/initial-dpr=([d.]+)/);
                        var maximumDpr = content.match(/maximum-dpr=([d.]+)/);
                        if (initialDpr) {
                            dpr = parseFloat(initialDpr[1]);
                            scale = parseFloat((1 / dpr).toFixed(2));
                        }
                        if (maximumDpr) {
                            dpr = parseFloat(maximumDpr[1]);
                            scale = parseFloat((1 / dpr).toFixed(2));
                        }
                    }
                }
    
                if (!dpr && !scale) {
                    var isAndroid = win.navigator.appVersion.match(/android/gi);
                    var isIPhone = win.navigator.appVersion.match(/iphone/gi);
                    var devicePixelRatio = win.devicePixelRatio;
                    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;
                        
                }
    
                docEl.setAttribute('data-dpr', dpr);
                if (!metaEl) {
                    metaEl = doc.createElement('meta');
                    metaEl.setAttribute('name', 'viewport');
                    metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
                    if (docEl.firstElementChild) {
                        docEl.firstElementChild.appendChild(metaEl);
                    } else {
                        var wrap = doc.createElement('div');
                        wrap.appendChild(metaEl);
                        doc.write(wrap.innerHTML);
                    }
                }
    
                function refreshRem() {
                    var width = docEl.getBoundingClientRect().width;
    
                    if (width / dpr > 768) {
                        width = 768 * dpr;
                    }
                    var rem = width / 7.5;
                    docEl.style.fontSize = rem + 'px';
                    flexible.rem = win.rem = rem;
                }
    
                win.addEventListener('resize', function () {
                    clearTimeout(tid);
                    tid = setTimeout(refreshRem, 300);
                }, false);
                win.addEventListener('pageshow', function (e) {
                    if (e.persisted) {
                        clearTimeout(tid);
                        tid = setTimeout(refreshRem, 300);
                    }
                }, false);
    
                if (doc.readyState === 'complete') {
                    doc.body.style.fontSize = 12 * dpr + 'px';
                } else {
                    doc.addEventListener('DOMContentLoaded', function (e) {
                        doc.body.style.fontSize = 12 * dpr + 'px';
                    }, false);
                }
    
    
                refreshRem();
    
                flexible.dpr = win.dpr = dpr;
                flexible.refreshRem = refreshRem;
                flexible.rem2px = function (d) {
                    var val = parseFloat(d) * this.rem;
                    if (typeof d === 'string' && d.match(/rem$/)) {
                        val += 'px';
                    }
                    return val;
                }
                flexible.px2rem = function (d) {
                    var val = parseFloat(d) / this.rem;
                    if (typeof d === 'string' && d.match(/px$/)) {
                        val += 'rem';
                    }
                    return val;
                }
    
            })(window, window['lib'] || (window['lib'] = {}));
        </script>

    flexible的缺点是对ui框架支持不好

  • 相关阅读:
    javascript:void(0)的作用示例
    JavaScript 字符串编码函数
    call和apply
    雪中情
    flask第二十篇——模板【3】
    flask第十九篇——模板【3】
    flask第十八篇——模板【2】
    flask第十七篇——模板【1】
    flask第十六篇——Response【2】
    flask第十五篇——Response
  • 原文地址:https://www.cnblogs.com/liuXiaoDi/p/12261100.html
Copyright © 2011-2022 走看看