zoukankan      html  css  js  c++  java
  • 移动端自适应布局方案尝试

    原文地址:移动端自适应布局方案尝试

    问题

    刚开始接触移动端H5页面的时候最困扰的几个问题是:

    1. 6或6p上明明是1px的边框怎么就成了2px或3px辣么粗!
    2. 图片,div等如何等比自适应设计图

    后来慢慢知道了第一点是由于retina屏幕下设备像素比的问题造成,第二点知道了单位rem。

    目的

    不想因为使用rem而一一去计算设计稿的尺寸,设计稿750的尺寸的标注可以直接在sass中使用;字体不使用rem缩放,原因是:

    显然,我们在iPhone3G和iPhone4的Retina屏下面,希望看到的文本字号是相同的。也就是说,我们不希望文本在Retina屏幕下变小,另外,我们希望在大屏手机上看到更多文本,以及,现在绝大多数的字体文件都自带一些点阵尺寸,通常是16px和24px,所以我们不希望出现13px和15px这样的奇葩尺寸。

    还一个目的是,在页面没有设置viewport的时候动态设置,并且不让页面有一个“闪现”的过程(也就是刚加载没设置的状态到设置的状态);页面动态变化时,尺寸相应变化;

    尝试

    在写H5页面的时候,尽可能少的去写meta标签,我会这样做:

    <head>
        <title>viewport test</title>
        <meta charset="utf-8">
        <link rel="stylesheet" href="style/style.css">
    </head>

    就这样简单,然后实现的代码当然是放在head里。因为并没有写viewport,所以得判断加上

    if (!metaEl) {
        metaEl = doc.createElement('meta');
        metaEl.setAttribute('name', 'viewport');
        metaEl.setAttribute('content', 'width=device-width,initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no');
        if (docEl.firstElementChild) {
            docEl.firstElementChild.appendChild(metaEl);
        } else {
            var wrap = doc.createElement('div');
            wrap.appendChild(metaEl);
            doc.write(wrap.innerHTML);
        }
    }

    然后根据页面的devicePixelRatio缩放

    var scale = parseFloat((1 / dpr).toFixed(2));
    if (dpr != 1) {
        metaEl.setAttribute('content', 'width=device-width,initial-scale='+ scale +', maximum-scale='+ scale +', minimum-scale='+ scale +', user-scalable=no');
    }

    设置根字体大小

    // document width
    function setDocumentFontSize () {
        var width = docEl.getBoundingClientRect().width;
        docEl.style.fontSize = width / 10 + 'px';
    }
    setDocumentFontSize();

    页面resize监听

    var timer;
    win.addEventListener('resize', function() {
        clearTimeout(timer);
        timer = setTimeout(function () {
            setDocumentFontSize();
        }, 300);
    }, false);

    为了字体不使用rem,需要为documentElement设置data-dpr属性

    // document data-dpr set font-size px
    var dpr = window.devicePixelRatio;
    if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {                
        dpr = 3;
    } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){
        dpr = 2;
    } else {
        dpr = 1;
    }
    docEl.setAttribute('data-dpr', dpr);

    sass相关设置

    完全根据设计稿尺寸写

    // baseFontSize 
    $baseFontSize: 75;
    @function px2rem($px){
        @return $px/$baseFontSize * 1rem;
    }
    @function px2rem2($px){
        @return px2rem($px*2);
    }

    字体大小变化

    // 字体大小计算
    @mixin font-dpr($font-size){
        font-size: $font-size;
    
        [data-dpr="2"] & {
            font-size: $font-size * 2;
        }
    
        [data-dpr="3"] & {
            font-size: $font-size * 3;
        }
    }

    例如:一个简单样式的设置,(在这里设计稿给的尺寸是300*auto,边框是1px)

    .test {
        @include font-dpr(10px);
        width: px2rem2(300);
        margin: 0 auto;
        border:1px #dcdcdc solid;
    }
    img {
        display: block;
        width: px2rem2(355);
        margin: 0 auto;
    }

    效果示例:

    可以从图中看出,6p的dpr为3,字体相应为30px,页面缩放了3倍,同时,1px边框在设备像素密度为3倍的情况下依旧显示的1px(因为被缩小了),正是我所想要的。

    页面demo源码

    <!DOCTYPE html>
    <html>
    <head>
        <title>viewport test</title>
        <meta charset="utf-8">
        <link rel="stylesheet" href="style/style.css">
        <script>
        ;(function (win) {
            var doc = win.document;
            var docEl = doc.documentElement;
            var metaEl = doc.querySelector('meta[name="viewport"]');
    
            if (!metaEl) {
                metaEl = doc.createElement('meta');
                metaEl.setAttribute('name', 'viewport');
                metaEl.setAttribute('content', 'width=device-width,initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no');
                if (docEl.firstElementChild) {
                    docEl.firstElementChild.appendChild(metaEl);
                } else {
                    var wrap = doc.createElement('div');
                    wrap.appendChild(metaEl);
                    doc.write(wrap.innerHTML);
                }
            }
    
            // document data-dpr set font-size px
            var dpr = window.devicePixelRatio;
            if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {                
                dpr = 3;
            } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){
                dpr = 2;
            } else {
                dpr = 1;
            }
            docEl.setAttribute('data-dpr', dpr);
    
            var scale = parseFloat((1 / dpr).toFixed(2));
            if (dpr != 1) {
                metaEl.setAttribute('content', 'width=device-width,initial-scale='+ scale +', maximum-scale='+ scale +', minimum-scale='+ scale +', user-scalable=no');
            }
    
            // document width
            function setDocumentFontSize () {
                var width = docEl.getBoundingClientRect().width;
                docEl.style.fontSize = width / 10 + 'px';
            }
            setDocumentFontSize();
    
            var timer;
            win.addEventListener('resize', function() {
                clearTimeout(timer);
                timer = setTimeout(function () {
                    setDocumentFontSize();
                }, 300);
            }, false);
        })(window);
        </script>
    </head>
    <body>
        
        <div class="test">
            显然,我们在iPhone3G和iPhone4的Retina屏下面,希望看到的文本字号是相同的。也就是说,我们不希望文本在Retina屏幕下变小,另外,我们希望在大屏手机上看到更多文本,以及,现在绝大多数的字体文件都自带一些点阵尺寸,通常是16px和24px,所以我们不希望出现13px和15px这样的奇葩尺寸。
        </div>
    
        <img src="https://camo.githubusercontent.com/3bd9e24ee11cee86e81dc49c0e5722e9f55e7297/687474703a2f2f7777772e773363706c75732e636f6d2f73697465732f64656661756c742f66696c65732f626c6f67732f323031352f313531312f72656d2d392e6a7067" alt="">
    </body>
    </html>

    欢迎关注我的博客:http://ymblog.net

  • 相关阅读:
    洛谷 P1990 覆盖墙壁
    洛谷 P1033 自由落体
    洛谷 P2049 魔术棋子
    洛谷 P2183 巧克力
    poj_1743_Musical Theme(后缀数组)
    Codeforces Round #367 (Div. 2) D. Vasiliy's Multiset
    Codeforces Round #367 (Div. 2) C. Hard problem
    hdu_5831_Rikka with Parenthesis II(模拟)
    hdu_5826_physics(物理题)
    hdu_5821_Ball(贪心)
  • 原文地址:https://www.cnblogs.com/jhmydear/p/5899322.html
Copyright © 2011-2022 走看看