h5 移动端适配最佳实践

news2024/10/12 14:17:34

移动端适配的方案需要根据具体的业务场景进行选择,工作中接触最多的是一些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 可以自动将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;
 }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2208106.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何使用ipopt进行非线性约束求目标函数最小值(NLP非线性规划)内点法(Interior point method)

非线性规划,一般用matlab调用cplex和gurobi了,但这两个一般用于线性规划和二次规划 线性规划LP,二次规划(quadratic programming),如果要求更一般的非线性规划IPOT是个很好的选择,求解器很多,根据情况自己选择 非线性 具体的,这篇文章介绍的很清楚了https://blog.csd…

Javascript笔试题目(一)

1.JS查找文章中出现频率最高的单词? 要在JavaScript中查找文章中出现频率最高的单词&#xff0c;你可以按照以下步骤进行操作&#xff1a; 将文章转换为小写&#xff1a;这可以确保单词的比较是大小写不敏感的。移除标点符号&#xff1a;标点符号会干扰单词的计数。将文章拆…

SpringBoot环境下的电商推荐网站开发全攻略

1系统概述 1.1 研究背景 如今互联网高速发展&#xff0c;网络遍布全球&#xff0c;通过互联网发布的消息能快而方便的传播到世界每个角落&#xff0c;并且互联网上能传播的信息也很广&#xff0c;比如文字、图片、声音、视频等。从而&#xff0c;这种种好处使得互联网成了信息传…

题目:1297. 子串的最大出现次数

> Problem: 1297. 子串的最大出现次数 题目&#xff1a;1297. 子串的最大出现次数 题目描述 给定一个字符串 s&#xff0c;要求找到满足以下条件的任意子串的出现次数&#xff0c;并返回该子串的最大出现次数&#xff1a; 子串中不同字母的数目必须小于等于 maxLetters。…

使用3080ti配置安装blip2

使用3080ti运行blip2的案例 本机环境&#xff08;大家主要看GPU&#xff0c;ubuntu版本和cuda版本即可&#xff09;&#xff1a;安装流程我最后安装的所有包的信息&#xff08;python 3.9 &#xff09;以供参考&#xff08;environment.yml&#xff09;&#xff1a; 本机环境&a…

Git:LF will be replaced by CRLF、pytest PermissionError以及Git应用中的一些问题解决及一些使用技巧

一、Git:LF will be replaced by CRLF和pytest: --cov NTERNALERROR PermissionError 1. git warning: LF will be replaced by CRLF in ***file 偶然git add在进行代码提交的时候碰到警告warning: LF will be replaced by CRLF in ***file&#xff0c;原因是编辑的代码内容中…

java抽象类和接口-cnblog

java抽象类和接口 1 抽象类 在解决实际问题时,一般将父类作为抽象类&#xff0c;子类继承父类&#xff0c;并且实例化对象 在一个类中&#xff0c;只要有有一个方法是抽象的&#xff0c;类就是抽象的 抽象类被继承后需要实现所有的抽象方法&#xff0c;抽象类的关键词是abst…

entity,pojo,vo,dto 详解

在Java项目中&#xff0c;包名通常用于组织代码&#xff0c;使其更加清晰和易于维护。entity、pojo、vo和dto是常见的包名&#xff0c;它们各自有不同的含义和用途。下面将详细解释这些包名的含义&#xff0c;并提供一个示例&#xff0c;帮助你更好地理解它们在项目中的应用。 …

第二届 龙信杯 电子数据取证竞赛部分Writeup

大佬文章&#xff1a; 龙信杯复现&#xff08;23、24&#xff09; | BthclsBlog 手机部分 资料&#xff1a;2024年第二届龙信杯 WP_2024龙信杯wp-CSDN博客 1.分析手机检材&#xff0c;请问此手机共通过adb连接过几个设备&#xff1f;[标准格式&#xff1a;3] 2 /data/a…

基于Java SpringBoot和Vue校园新闻论坛管理系统设计

摘要 本系统采用Java Spring Boot作为后端框架&#xff0c;前端使用Vue.js构建用户界面&#xff0c;旨在为校园新闻论坛提供一个高效、易用且功能全面的管理平台。通过整合SpringBoot的快速开发优势与Vue的响应式设计&#xff0c;实现了一个包含用户注册登录、新闻发布审核、评…

Rust编程的泛型

【图书介绍】《Rust编程与项目实战》-CSDN博客 《Rust编程与项目实战》(朱文伟&#xff0c;李建英)【摘要 书评 试读】- 京东图书 (jd.com) Rust编程与项目实战_夏天又到了的博客-CSDN博客 7.6.1 什么是泛型编程 C/C、Rust都是强类型语言&#xff0c;在对数据进行处理时&a…

详解前端开发都需要掌握的十个 JavaScript 基本数组函数

假设你正在开发一个复杂的 Web 项目。你的数据来自许多 API&#xff0c;你的工作是高效地处理、过滤和分析这些数据。你的时间很紧张&#xff0c;所以每一行代码都很重要。 这时学习高级 JavaScript 数组方法就会对你有所帮助。 这些函数不仅可以减少代码量&#xff0c;还可以…

C语言—双链表

一、双向链表的结构 注意&#xff1a;这⾥的“带头”跟前⾯我们说的“头节点”是两个概念&#xff0c;实际前⾯在单链表阶段称呼不严谨&#xff0c;带头链表⾥的头节点&#xff0c;实际为“哨兵位”&#xff0c;哨兵位节点不存储任何有效元素&#xff0c;只是站在这⾥“放哨的”…

desmos和webgl绘制线条

目录 desmos绘制 webgl绘制 将线段坐标生成三角化坐标 处理斜接线段 处理圆角 尖角 先在desmos上面完成线条lineJoin绘制的,再将代码和公式转到js用webgl绘制. desmos绘制 示例 desmos计角斜接角时&#xff0c;需要用到的一些函数。在desmos定义成公共函数&#xff0c…

[含文档+PPT+源码等]精品基于springboot实现的原生Andriod心理健康辅导平台

基于Spring Boot实现的原生Android心理健康辅导平台&#xff0c;其背景可以从以下几个方面进行详细阐述&#xff1a; 一、技术背景 Spring Boot框架&#xff1a;Spring Boot是Spring框架的一个子集&#xff0c;它通过自动配置、简化依赖管理、内嵌容器等特性&#xff0c;极大…

登录前端笔记(一):pinia管理用户数据

一、把pinia加入到项目文件里 ①、npm install pinia ②mian.ts //①导入createPinia import { createPinia } from pinia //②执行方法得到实例 const pinia createPinia() //③把pinia实例加入到APP应用里 app.use(pinia)二、官网简单实例&#xff08;定义store【state与ac…

Stylized Far East 古代国风建筑城镇宫殿场景模型

古代国风建筑城镇宫殿场景模型。内容: -演示场景(截图) - 种类繁多的建筑,如宫殿、商店、神社、房屋、餐馆、宝塔、寺庙等 -带有塔楼、门楼的模块化城堡墙 -树木、岩石、悬崖和其他自然资产 -传统装饰,如纸灯笼、绘画、瓷器等 - 城镇道具,如手推车、栅栏、板条箱、市场、…

Redis-缓存一致性

缓存双写一致性 更新策略探讨 面试题 缓存设计要求 缓存分类&#xff1a; 只读缓存&#xff1a;&#xff08;脚本批量写入&#xff0c;canal 等&#xff09;读写缓存 同步直写&#xff1a;vip数据等即时数据异步缓写&#xff1a;允许延时&#xff08;仓库&#xff0c;物流&a…

el-carousel-item自动重复渲染,使用nanoid让重复的元素包含不同的id

<template><div class"page-container"><div class"m-title">轮播图</div><el-carousel height"400px" :autoplay"true"><el-carousel-item v-for"(item, index) in carouselList" :key&…

AOT漫谈专题(第二篇): 如何对C# AOT轻量级APM监控

一&#xff1a;背景 1. 讲故事 上一篇我们聊到了如何调试.NET Native AOT 程序&#xff0c;这是研究一个未知领域知识的入口&#xff0c;这篇我们再来看下如何对 Native AOT 程序进行轻量级的APM监控&#xff0c;当然这里的轻量级更多的是对 AOT 中的coreclr内容的挖掘。 二…