Rem 等比适配始末

栏目: CSS · 发布时间: 7年前

内容简介:Rem 等比适配始末

Viewport 等比适配始末 说过使用 Viewport 来实现等比适配的例子,本文详解等比适配的另一种方式

推导

拿到一个宽度为 vWidth 的视觉稿

设设备屏幕宽度为 dWidth

在视觉稿上量得一个元素的宽度为 eleVWidth

那么要实现 按照宽度等比适配 ,在各种设备中元素的实际宽度 x 将满足公式

//等比
    eleVWidth/vWidth = X/dWidth;

    //我们的目的是求X
    X = (eleVWidth/vWidth)dWidth;

拿到视觉稿之后,eleVWidth 和 vWidth 都已经固定了,但是 dWidth 在不同的设备中确实不同的,而且需要实际运行的时候我们才能拿到 dWidth,这个时候就要利用 rem 的特性了, 我们通过阻塞运行的 js 动态设置 rem,使得 rem=dWdith/10 ,套入刚才的公式:

X=(eleVWidth/vWidth)*10*rem

    //体现在css中
    .className {
        width: (eleVWidth/vWidth)*10 rem
    }

为什么设置是 dWdith/10 呢?方便计算而已,当然也可以除以别的基数,但是尽量不要让 rem 太小,有兼容性问题

动态设置rem

这段 css 需要放在 body 标签的开始位置,因为 rem 值要尽可能早的设置成功,避免无谓的重排重绘(有些设备中若元素样式已经生效,动态改变 rem 未必能起作用,所以这个动作更需要提前)

<body>
        <script>
        (function() {
            var ua = window.navigator.userAgent;
            var docEl = document.documentElement;
            var html = document.querySelector('html');
            var isAndorid = /Android/i.test(ua);
            var dpr = window.devicePixelRatio || 1;
            var rem = docEl.clientWidth / 10;

            // 设置 rem 基准值
            html.style.fontSize = rem + 'px';

            // Nexus 5 上 rem 值不准,
            // 如:设置100px,getComputedStyle 中的值却为 85px,导致页面错乱
            // 这时需要检查设置的值和计算后的值是否一样,
            // 不一样的话重新设置正确的值
            var getCPTStyle = window.getComputedStyle;
            var fontSize = parseFloat(html.style.fontSize, 10);
            var computedFontSize = parseFloat(getCPTStyle(html)['font-size'], 10);
            if (getCPTStyle && Math.abs(fontSize - computedFontSize) >= 1) {
                html.style.fontSize = fontSize * (fontSize / computedFontSize) + 'px';
            }

            // 设置 data-dpr 属性,留作的 css hack 之用
            html.setAttribute('data-dpr', dpr);

            // 安卓平台额外加上标记类
            if (isAndorid) {
                html.setAttribute('data-platform', 'android');
            }
        })();
        </script>
        ...
    </body>

css 中应该怎么写

如果每在视觉稿上量出一个值,在写到样式文件之前都得通过那个公式计算一翻,那绝对不是一个好策略,我们希望量到啥就写啥

使用 less,sass 等 css 预处理器的函数

//设计稿为640
    @function rem($val) {
        @return $val/64 * 1rem;;
    }

    //设计稿为750
    @function rem750($val) {
        @return $val/75 * 1rem;
    }

    //使用
    .className {
        width: @rem(100);
    }

也可以使用 webpack-loader,例如:change-rem-loader,这个 loader 代码做的事也是上述的转化计算(写一个 webpack loader 并不复杂,你可以自己写一个符合自己情况的 loader)

    'use strict';
    module.exports = function(source) {
        source = source.replace(/rem(\d*)\((.*?)\)/g, function(match, type, value) {
            var divVal;

            // 不做 try catch,及早发现错误以免造成故障
            switch (type) {
                // 1080宽度的设计稿,rem1080(value)
                case '1080':
                    divVal = 108;
                    break;
                    // 默认为750宽度的设计稿,rem(value)
                case '750':
                    divVal = 75;
                    break;
                default:
                    divVal = 64;
            }

            return (value / divVal).toFixed(6) + 'rem';
        });
        return source;
    }

这样之后,我们 css 同样可以这样写(如何让 loader 起作用不是本文的范围)

.className {
        width: rem(100);
    }

也许你的工程技术栈里面,使用的不是 webpack,也没有使用 less、sass 等预处理器,那你可以根据你的实际情况去寻找一种预处理方案,只要达到推导公式的效果就可以了。

什么?没有合适的方案,那你是时候充充电了

期待您的关注~~


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Java核心技术及面试指南

Java核心技术及面试指南

金华、胡书敏、周国华、吴倍敏 / 北京大学出版社 / 2018-9-1 / 59.00

本书根据大多数软件公司对高级开发的普遍标准,为在Java 方面零基础和开发经验在3 年以下的初级程序员提供了升级到高级工程师的路径,并以项目开发和面试为导向,精准地讲述升级必备的技能要点。具体来讲,本书围绕项目常用技术点,重新梳理了基本语法点、面向对象思想、集合对象、异常处理、数据库操作、JDBC、IO 操作、反射和多线程等知识点。 此外,本书还提到了对项目开发很有帮助的“设计模式”和“虚拟......一起来看看 《Java核心技术及面试指南》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具