这是我参与更文挑战的第18天,活动详情查看: 更文挑战 !
👽 概论
各种大小的页面的自适应一直是困扰每位前端开发者的一大难题,为了解决这一问题,大家相出了很多方案:1. 百分比布局;2. 媒体查询;3. vw/vh布局;4. transform缩放;5. em布局;6. rem布局等等。这些方案各有千秋,但没有一个算得上十全十美。若要提起其中运用最为广泛的方案,便首推rem布局。
传统的rem布局方案,在引入rem转化方法后,需要通过pxtorem插件对项目中的单位做后置转化处理。name有没有一种方法可以在开发时便直接输入rem单位,免去后期转换的烦恼呢?答案就是pxCook。
👽 rem布局
在正式介绍pxcook前,让我们先来回顾一下rem的相关知识点。
👻 原理
传统的px布局的痛点就在于,1px不管是在大屏还是在小屏上大小都是一致的。这就导致同样是1000px的盒子,在大屏上表现正常,小屏上就会出现放不下或错位的情况。
在探索响应式处理的各种方案中,除媒体查询与transform之外,其余方案的本质还是与百分比相关。试想一下,虽然大屏与小屏的长宽不尽相同,但我们若是将其同等分成若干份,每份对应展示的内容保持一致,不就是我们想要的结果吗?将其转化为数学公式就是:
怎么动态的设置不同屏幕尺寸下的rem便成了下一步要解决的关键。
👻 动态rem实现
下面我们就来一步步解析简易flexible.js的实现过程:
// 创建一个用于动态设置rem的立即执行函数
(function flexible() {
// 获取根元素
let docEl = document.documentElement;
// 获取设备的dpr,即当前设置下物理像素与虚拟像素的比值
let dpr = window.devicePixelRatio || 1;
// 此处便是在动态设置rem
function setRemUnit() {
// 之前说的‘若干份’此处定义为48
// 设置根元素的fontSize = 其clientWidth / 4 + 'px' = 1rem
let rem = docEl.clientWidth / 48;
docEl.style.fontSize = rem + "px";
}
setRemUnit();
// 当页面展示或重新设置大小的时候,重新触发
window.addEventListener("resize", setRemUnit);
window.addEventListener("pageshow", e=> {
e.persisted && setRemUnit();
});
// 检测0.5px的支持,支持则root元素的class中有hairlines
if (dpr >= 2) {
let fakeBody = document.createElement("body");
let testElement = document.createElement("div");
testElement.style.border = ".5px solid transparent";
fakeBody.appendChild(testElement);
docEl.appendChild(fakeBody);
if (testElement.offsetHeight === 1) {
docEl.classList.add("hairlines");
}
docEl.removeChild(fakeBody);
}
})();
👻 vue项目中的引入
直接在main.js
引入即可:
import Vue from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
import './utils/flexible';
Vue.config.productionTip = false;
new Vue({
router,
store,
render: h => h(App),
}).$mount('#app');
👽 pxcook
pxcook是前端必不可少的一款协作开发工具,它可以实现设计图自动标注以及生成前端代码的功能。此处我们主要是使用其自动标注功能。
👻 基本使用
🙋在导入psd设计稿到pxcook时,选择web项目:
🙋 查看设计稿的px宽度,切换至rem单位设置基数(基数 = 设计稿px宽度 / ‘若干份’)。 比如1920px的宽度分48份,name基数就是40px
此时便可获得其rem大小,将其直接写在项目中。当然也可以直接复制自动生成的css代码(大概还是有80%准确率的)。
👽 结语
铁汁们,有更好方法的话欢迎友善交流~