首页 > 其他分享 >h5 移动端适配最佳实践

h5 移动端适配最佳实践

时间:2024-10-29 13:20:37浏览次数:1  
标签:document 适配 px h5 最佳 window rem 1rem postcss

移动端适配的方案需要根据具体的业务场景进行选择,工作中接触最多的是一些h5活动页、落地页等,这些页面在大小屏手机上的展示要求大小屏无差异,那么就针对以上要求进行项目整体的适配是最合适不过的。 如果是大屏手机展示更多的内容,并不着重于放大展示的话,外层布局使用vw,%,flex,内层直接px的混合适配的方案更加合适。

实现方案

方案一:手写vw+vh方案

 换算vw、vh函数的实现:

@mixin px-to-vw($px, $design-width: 375) { // $design-width:设计稿大小
  width: calc(#{$px} / #{$design-width} * 100vw);
}

.element {
  @include px-to-vw(50); /* 将 50px 转换为基于 375px 设计稿宽度的 vw */
}

方案二:手写rem+vw方案

换算rem函数的实现:

// 基础字体大小以vw为单位
$base-font-size: 0.43vw;

@function px-to-rem($px) {
  @return #{$px / $base-font-size}rem;
}

.element {
  font-size: px-to-rem(16);      // 结果是 1rem
  padding: px-to-rem(24) px-to-rem(32); // 结果是 1.5rem 2rem
}

方案三:postcss-pxtorem + amfe-flexible

postcss-pxtorem

借助第三方库 postcss-pxtorem 可以自动将px转换成rem,不需要手动计算,按照以下配置即可:

module.exports = {
  css: {
      postcss: {
        plugins: [
          require('postcss-pxtorem')({
            rootValue: 16, // 基准字体大小, 1rem = 16px
            unitPrecision: 3,  // 保留的小数位数
            propList: ['*'], // 需要转换的属性, * 表示全部属性
            minPixelValue: 1 // 设置最小的转换数值
          })
        ]
      }
    }
  }
 }

这一步实现了px到rem单位的转换,但是基准值 rootValue 写的16 (1rem = 16px) , 如果不动态调整font-size,页面将无法响应不同设备的尺寸变化。

amfe-flexible

借助第三方库 amfe-flexible 根据设备屏幕宽度大小自动调整font-size:

// Install
npm i -S amfe-flexible

// Import
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
<script src="./node_modules/amfe-flexible/index.js"></script>

需要注意的是,amfe-flexible 计算 1rem 的方式是 设备屏幕宽度/10,源码如下所示 :

  // set 1rem = viewWidth / 10
  function setRemUnit () {
    var rem = docEl.clientWidth / 10
    docEl.style.fontSize = rem + 'px'
  }

 

那么需要将 postcss-pxtorem 中 rootValue 设置为 设计稿的宽度/10,假设设计稿的宽度大小是375,那么对应的rootValue(1rem)设置为 37.5

 
module.exports = {
  css: {
      postcss: {
        plugins: [
          require('postcss-pxtorem')({
            rootValue: 37.5, // 设计稿大小/10
     // ...
 }

此方案将屏幕拆分成10份,假设屏幕宽度是375,那么1rem = 37.5px,即 1px = 0.02666667rem 那么反过来计算元素大小为37.5px时0.02666667rem x 37.5 = 1.000000012 会存在轻微的误差。 

 

方案四:postcss-pxtorem + 手写实现flexible.js

 针对 amfe-flexible 存在的问题,可以自己设置基准值,例如 1rem = 50px:

  function setRootPixel() {
    var defaultFontSize = 0;

    function getDefaultFontSize() {
      if (defaultFontSize) {
        return defaultFontSize;
      }

      document.documentElement.style.fontSize = "";
      var temp = document.createElement("div");
      temp.style.cssText = "width:1rem;display:none";
      document.head.appendChild(temp);
      defaultFontSize =
        +window
          .getComputedStyle(temp, null)
          .getPropertyValue("width")
          .replace("px", "") || 16;
      document.head.removeChild(temp);

      return defaultFontSize;
    }

    function setRootFontSize() {
    // 预设的基准值,此处的值与rootValue相等即可
      var rem2px = 50;
      var clientWidth =
        window.innerWidth && document.documentElement.clientWidth
          ? Math.min(window.innerWidth, document.documentElement.clientWidth)
          : window.innerWidth ||
            document.documentElement.clientWidth ||
            (document.body && document.body.clientWidth) ||
            375;
    // 在设计稿是375的情况下1rem = 50px,此处则根据实际的clientWidth来计算根元素 `<html>` 的 `font-size` 值
      var htmlFontSizePx = (clientWidth / 375) * rem2px;

      window.ROOT_FONT_SIZE = htmlFontSizePx;

      var htmlRootElement = document.querySelector("html");
      if (htmlRootElement) {
      // 通过相对于原来字体百分比大小的形式来设置字体大小
        htmlRootElement.style.fontSize =
          (htmlFontSizePx / getDefaultFontSize()) * 100 + "%";
      }
    }

    function adjust(immediate) {
      if (immediate) {
        setRootFontSize();
        return;
      }

      setTimeout(setRootFontSize, 30);
    }

    adjust(true);

    window.addEventListener("resize", adjust, false);

    if ("onorientationchange" in window) {
      window.addEventListener("orientationchange", adjust, false);
    }
  }

  typeof window !== "undefined" && setRootPixel();

假设rootValue为50(1rem = 50px),那么flexible中划分的份数 = 设计稿大小/50 ,再通过 实际屏幕大小/划分的份数计算出根元素 <html> 的 font-size 值。 

总结

两种方案都使用了postcss-pxtorem,都是在编译时对单位进行了转换,在实际的业务场景中会通过js设置动态样式,自行实现转换函数:

 

/**
 * px转rem
 * @param px 375屏宽下的px值
 * @param unit 是否需要rem单位,默认true
 * @returns rem值
 */

 export function px2rem(px: number, unit?: true): string;
 export function px2rem(px: number, unit: false): number;
 export function px2rem(px: number, unit = true) {
     const rem = Math.floor((px / 50) * 1000000) / 1000000;
     if (unit) {
         return `${rem}rem`;
     }
 
     return rem;
 }
作者:吃嘛嘛香呼呼
链接:https://juejin.cn/post/7408798040520556559
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

标签:document,适配,px,h5,最佳,window,rem,1rem,postcss
From: https://www.cnblogs.com/shangguancn/p/18512873

相关文章

  • Vue3 - 完美解决html2canvas截图不全问题,截图只截取当前可视区域导出图片不全,截屏导出
    前言该解决方案任意前端技术栈通用,不仅限Vue。在vue3(手机H5移动端/微信公众号H5页面)项目开发中,使用html2canvas截屏时发现有一部分未截取到少了一块截图不完整,导出保存图片时发现截图只有一半显示不全,另外还有一个问题就是截图时截取当前可视区域的问题(出现滚动条只保......
  • 一站式搭建交友平台-交友系统源码-H5小程序app有什么优势?
    一站式搭建交友平台、交友系统源码以及H5小程序app交友系统平台是当前社交软件开发领域的热门话题。以下是对这些概念的详细解析:一站式搭建交友平台一站式搭建交友平台指的是通过一套完整的解决方案,快速构建并上线一个功能齐全的交友平台。这种解决方案通常包括平台设计、开......
  • ArkTS 中的内存调优与配置:最佳实践
    本文旨在深入探讨华为鸿蒙HarmonyOSNext系统(截止目前API12)的技术细节,基于实际开发实践进行总结。主要作为技术分享与交流载体,难免错漏,欢迎各位同仁提出宝贵意见和问题,以便共同进步。本文为原创内容,任何形式的转载必须注明出处及原作者。引言HarmonyOSNext的内存管理与垃......
  • httpsok:自动续期SSL证书的最佳选择!
    一、引言        在数字化时代,网站的安全性至关重要,而SSL证书是保护用户数据、提升网站信誉的关键。然而,证书的续期往往令人头痛。今天,我们为你介绍一款高效的SSL证书自动续期工具——httpsok,让你的证书管理变得轻松无忧。二、什么是httpsok?httpsok是一款专为网站......
  • 在K8S中,可以采取的最佳安全措施是什么?
    在Kubernetes(K8s)中,为了确保集群的安全性,可以采取一系列最佳安全措施。以下是一些关键的最佳实践:网络安全网络策略:定义Pod间的网络通信规则,控制进出Pod的流量,以减少潜在的攻击面。防火墙与访问控制:配置节点防火墙限制对集群节点不必要的外部访问,仅允许来自受信任来源的必要服......
  • 数据科学项目管理的最佳实践
    文章开头段落:数据科学项目管理的最佳实践包括项目定义与规划、团队构建与合作、数据管理、流程与工具、沟通与报告。其中,项目定义与规划是项目成功的关键因素,它要求明确项目的目标、范围、时间线和预期结果。在这一阶段中,以问题为导向,制定合理的假设条件、识别关键假设,并为接下......
  • 代码随想录算法训练营day27| 122.买卖股票的最佳时机II 55. 跳跃游戏 45.跳跃
    学习资料:https://programmercarl.com/0122.买卖股票的最佳时机II.html#算法公开课贪心PART2学习记录:122.买卖股票的最佳时间2(求最大利润,贪心:把所有正数相加;后一天与当天的股票价格差值,若为正就加入利润,若为负,则不加)点击查看代码classSolution:defmaxProfit(self,pr......
  • 【详解】多状态DP:买卖股票的最佳时机 系列问题
    一.解法思路买卖股票的最佳时机系列是十分经典的多状态DP问题。分析这种多状态DP问题我们可以借助状态机的思想。我们可以根据问题分析出这个问题有几个状态,每个状态之间是怎么转化的。通过转化的方式我们可以写出状态转移方程。状态转移方程这个很好理解,就是状态要转移时要付......
  • PHP中的错误处理最佳实践
    在PHP中,错误处理最佳实践包括错误日志记录、使用异常处理机制、设置自定义错误处理器,和配置错误报告级别。其中,使用异常处理机制可以让代码更加健壯,并且易于调试。异常处理允许开发者将错误处理代码与业务逻辑分离,使得后者更清晰,更准确地反映出程序应有的流程。通过抛出异常,代码......
  • 一款轻量级集成国密加解密系统,将实现国产化机型、中间件、数据库适配、工作流BPM、多
    前言随着信息技术的不断发展,国内对于实现国产化机型、中间件、数据库适配的需求日益增长,信创产业逐渐成为热点。传统的Java应用开发中,Spring与SpringCloud几乎是不可少的选择,它们占据了JavaWeb开发的重要位置。然而,在新的背景下,开-发者们需要一种更为轻量级、灵活且能够适......