前端多端适配之 postcss-plugin-px2rem 的使用及其原理实现

前端多端适配之 postcss-plugin-px2rem

前记

这个插件是可以将css中的像素转换成rem的插件,看这个插件的名字 px2rem => px "to" rem。主要用于适应不同的分辨率的移动设备,从而实现响应式布局。

如何使用

  • 下载
js 复制代码
npm i --save postcss-plugin-px2rem
  • 配置

postcss-plugin-px2rem 可以原生使用,也可以配合webpack,作为插件进行使用,这里写的是在 webpack.config.js 中配置 postcss-plugin-px2rem。

js 复制代码
import webpack from 'atool-build/lib/webpack';
import px2rem from 'postcss-plugin-px2rem';
 
export default webpackConfig => {
  const px2remOpts = {
      rootValue: 75, // 根元素的字体大小,一般为设计稿宽度/10,比如设计稿宽度为750px,则 rootValue 为 75 
      unitPrecision: 5, // 转换后的 rem 值精度
      propList: ['*'], // 需要转换的 CSS 属性,* 表示所有        
      exclude: /(node_module)/ // 排除转换的文件路径,一般排除 node_modules 目录
  };
  webpackConfig.postcss.push(px2rem(px2remOpts));
 
  return webpackConfig;
};
  • 使用效果
css 复制代码
/* 在设计稿中宽度为 100px 的元素,可以这样编写 CSS */ 
.example { width: 100px;
          font-size: 16px;
          }
          
// 转换为
/* 在实际页面中宽度为 1.333rem 的元素 */ 
.example { 
          width: 1.33333rem; 
          font-size: 0.21333rem; 
          }

实现原理

基础

前端开发移动端及H5的时候,不需要再关心移动设备的大小,只需要按照固定设计稿的px值布局。

  • dpr(设备像素比) css的像素px不等于设备像素/分辨率/各种值,css的px可以简单理解为虚拟像素,与设备无关,css的px需要乘dpr计算为设备像素;

  • css3 的 rem, 即"root em",是相对于根元素的font-size来做计算;配合js根据设备的dpr设置html的font-size="XX"来实现等比缩放

  • 基于 viewport 的长度单位:

    vw:即Viewport's width,1vw等于window.innerWidth的1%,所以窗口宽度是100vm

    vh:和vw类似,即Viewport's height,1vh等于window.innerHeihgt的1%

    vmin:vmin的值是当前vw和vh中较小的值

    vmax:vmax的值是当前vw和vh中较大的值

    总体来说,就是将px通过预定义的配置,根据不同的dpr计算为rem/vw,来实现不同屏幕大小的响应式伸缩。

实现核心

  • 代码
scss 复制代码
// $px 设计图上元件的尺寸
// $design-width  设计图尺寸
// $block  视口宽度被html的font-size切分的块数
$design-width: 375;
$blocks: 10;
@function px2rem($px) {
  @return #{$px / $design-width * $block}rem;
};

html{
  font-size: 10vw;
}
  • 说明

计算出设计图上元件的宽度相对于设计图尺寸的宽度比值: <math xmlns="http://www.w3.org/1998/Math/MathML"> p x / px / </math>px/design-width,假设设计图尺寸==视口宽度:假设设计图为375px 视口为100vw 那么让375px == 100vw 然后通过rem单位去实现这个换算。html的font-size把页面切分:如果font-size是10vw,相当于把页面切分成10块, <math xmlns="http://www.w3.org/1998/Math/MathML"> d e s i g n − w i d t h / 10 = = 10 v w 。 design-width / 10 == 10vw。 </math>design−width/10==10vw。px / <math xmlns="http://www.w3.org/1998/Math/MathML"> d e s i g n − w i d t h ∗ design-width * </math>design−width∗block 就得出了转换为rem之后的值。

总结

如果是多个入口的话,可以根据不同的入口设置不同的样式文件定义相对应的font-size。

相关推荐
小二·1 小时前
Python Web 开发进阶实战 :AI 原生数字孪生 —— 在 Flask + Three.js 中构建物理世界实时仿真与优化平台
前端·人工智能·python
Whisper_Sy1 小时前
Flutter for OpenHarmony移动数据使用监管助手App实战 - 网络状态实现
android·java·开发语言·javascript·网络·flutter·php
新缸中之脑2 小时前
Weave.js:开源实时白板库
开发语言·javascript·开源
Amumu121382 小时前
Vue组件化编程
前端·javascript·vue.js
We་ct2 小时前
LeetCode 6. Z 字形变换:两种解法深度解析与优化
前端·算法·leetcode·typescript
码农水水3 小时前
中国邮政Java面试被问:容器镜像的多阶段构建和优化
java·linux·开发语言·数据库·mysql·面试·php
小二·3 小时前
Python Web 开发进阶实战(终章):从单体应用到 AI 原生生态 —— 45 篇技术演进全景与未来开发者生存指南
前端·人工智能·python
m0_637256583 小时前
vue-baidu-map添加了类型组件导致非常卡顿的问题
前端·javascript·vue.js
雨季6664 小时前
基于设备特征的响应式 UI 构建:Flutter for OpenHarmony 中的智能布局实践
javascript·flutter·ui
挂机且五杀4 小时前
为什么在React地图组件里,memo 不是优化,而是生存?
前端·react.js·前端框架