内容简介: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 等预处理器,那你可以根据你的实际情况去寻找一种预处理方案,只要达到推导公式的效果就可以了。
什么?没有合适的方案,那你是时候充充电了
期待您的关注~~
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- JavaScript DOM元素长宽等比例缩放
- 网页图片等比例缩小实现方案总结以及最佳实践
- 迁移密码管理器始末,从 KeePass 到 Pass
- HQChart 1.9334 版本发布,增加等比坐标、黄金分割坐标、等分坐标
- “伪造转账通知”漏洞细节披露:EOSBet遭黑客攻击损失近14万EOS始末
- 5 亿微博隐私数据被爆遭泄漏始末,国际暗网正在火爆交易
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Masterminds of Programming
Federico Biancuzzi、Chromatic / O'Reilly Media / 2009-03-27 / USD 39.99
Description Masterminds of Programming features exclusive interviews with the creators of several historic and highly influential programming languages. Think along with Adin D. Falkoff (APL), Jame......一起来看看 《Masterminds of Programming》 这本书的介绍吧!