webpack进阶篇(十六):移动端 CSS px 自动转换成 rem

简介: webpack进阶篇(十六):移动端 CSS px 自动转换成 rem

说明

玩转webpack课程学习笔记。



浏览器的分辨率

20200625234017430.PNG


CSS 媒体查询实现响应式布局

缺陷:需要写多套适配样式代码

@media screen and (max-width: 980px) {
  .header {
    width: 900px;
  }
}
@media screen and (max-width: 480px) {
  .header {
    height: 400px;
  }
}
@media screen and (max-width: 350px) {
  .header {
    height: 300px;
  }
}


rem 是什么


W3C 对 rem 的定义: font-size of the root element

  • rem 是相对单位
  • px 是绝对单位


移动端 CSS px 自动转换成 rem


1、使用 px2rem-loader

npm i px2rem-loader -D

2、页面渲染时计算根元素的 font-size

npm i lib-flexible -S

3、手动添加flexible

找到node_modules\lib-flexible\flexible.js,复制到search.html文件里面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <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 > 540) {
                    width = 540 * dpr;
                }
                var rem = width / 10;
                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>
</head>
<body>
    <div id="root"></div>
</body>
</html>


5、不转化怎么处理

后面有 /*no*/ 这种注释语法会不进行 rem 的转换

@font-face{
  font-family: 'SourceHanSerifSC-Heavy';
  src: url('./fonts/SourceHanSerifSC-Heavy.otf') format('truetype');
}
.search-text {
  font-size: 43px;
  width: 200px; /* no */
  color: green;
  font-family: 'SourceHanSerifSC-Heavy';
  display: flex;
}


6、效果

20200625234610835.PNG


目录
相关文章
|
17天前
|
JSON 移动开发 数据格式
html5+css3+js移动端带歌词音乐播放器代码
音乐播放器特效是一款html5+css3+js制作的手机移动端音乐播放器代码,带歌词显示。包括支持单曲循环,歌词显示,歌曲搜索,音量控制,列表循环等功能。利用json获取音乐歌单和歌词,基于html5 audio属性手机音乐播放器代码。
66 6
|
28天前
|
前端开发 UED
Webpack 中处理 CSS 和图片资源的多 Loader 配置
【10月更文挑战第12天】 处理 CSS 和图片资源是 Webpack 配置中的重要部分。通过合理选择和配置多个 Loader,可以实现对这些资源的精细处理和优化,提升项目的性能和用户体验。在实际应用中,需要不断探索和实践,根据项目的具体情况进行灵活调整和优化,以达到最佳的处理效果。通过对 Webpack 中多 Loader 处理 CSS 和图片资源的深入了解和掌握,你将能够更好地应对各种复杂的资源处理需求,为项目的成功构建和运行提供坚实的基础。
52 1
移动端的打开方式,打开F12之后,就可以看到手机样式设计,移动端的初始化使用normalize.css代码库录到,box-sizing: border-box; 定宽度为多少就是多少,代码库,移动端
移动端的打开方式,打开F12之后,就可以看到手机样式设计,移动端的初始化使用normalize.css代码库录到,box-sizing: border-box; 定宽度为多少就是多少,代码库,移动端
|
3月前
|
前端开发 UED
触屏新体验:CSS动画让移动端底部导航活起来!
触屏新体验:CSS动画让移动端底部导航活起来!
|
3月前
|
前端开发 JavaScript Serverless
揭秘CSS布局神器:vw/vh、rem、%与px大PK,掌握它们,让你的网页设计秒变高大上,面试难题迎刃而解!
【8月更文挑战第4天】在Web开发中,合理选择CSS单位对响应式布局至关重要。本文探索viewport单位(vw/vh)、rem、百分比(%)及像素(px)的基础知识与应用场景。通过代码示例,展示如何运用这些单位实现全屏布局、尺寸比例调整、灵活的元素大小及固定尺寸。最后,模拟面试题,介绍如何仅用CSS实现一个元素的高度为其宽度两倍且响应视口变化的方法。
255 8
|
3月前
|
前端开发
css中px和em的区别
css中px和em的区别
60 0
|
3月前
|
前端开发
css中px和em的区别
css中px和em的区别
|
3月前
|
前端开发
CSS——如何使网页字体小于12px
CSS——如何使网页字体小于12px
36 0
|
4月前
|
编解码 前端开发
CSS【详解】长度单位 ( px,%,em,rem,vw,vh,vmin,vmax,ex,ch )
CSS【详解】长度单位 ( px,%,em,rem,vw,vh,vmin,vmax,ex,ch )
66 0

热门文章

最新文章