大屏适配方案汇总

news2024/9/21 0:41:43

1. 适配方案1:rem + font-size

我们都知道,在 css1rem 等于 html 根元素设定的 font-sizepx 值,通过动态的修改html 根元素的 font-size 大小就能动态的改变 rem 的大小,从而实现适配。

原理

  1. 动态设置 HTML 根字体大小
  2. px 转成 rem

实现

  1. 引入 lib-flexible 动态设置 HTML 根字体大小和 body 字体大小。
(function flexible(window, document) {
  var docEl = document.documentElement;
  var dpr = window.devicePixelRatio || 1;

  // 调整 body 字体大小
  function setBodyFontSize() {
    if (document.body) {
      // body 字体大小默认为 16px
      document.body.style.fontSize = 16 * dpr + "px";
    } else {
      document.addEventListener("DOMContentLoaded", setBodyFontSize);
    }
  }
  setBodyFontSize();

  // 移动端默认平均分成 10 等分(适用移动端)
  // pc端默认平均分成 24 等分(适用 pc 端)
  function setRemUnit() {
    var splitNum = /Mobi|Android|iPhone/i.test(navigator.userAgent) ? 10 : 24;
    var rem = docEl.clientWidth / splitNum; // 1920 / 24 = 80
    docEl.style.fontSize = rem + "px"; // 设置 html 字体的大小 80px
  }

  setRemUnit();

  // 页面调整大小时重置 rem 单位
  window.addEventListener("resize", setRemUnit);
  window.addEventListener("pageshow", function (e) {
    if (e.persisted) {
      setRemUnit();
    }
  });

  // 检测 0.5px 支持
  if (dpr >= 2) {
    var fakeBody = document.createElement("body");
    var 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);
  }
})(window, document);
  1. pxrem

    pxrem 的方式有很多种:手动、less/scss 函数、cssrem 插件、webpack 插件、**Vite 插件。

  • cssrem 插件转换

    vscode root font-size 设置为 80px。这个是 px 单位转 rem 的参考值。

    image.png

    接着就可以按照 1920px * 1080px 的设计稿愉快开发,此时页面已经是响应式,并且宽高比不变

    image.png

  • webpack 插件转换

    安装

    npm i webpack webpack-cli -D
    npm i style-loader css-loader html-webpack-plugin -D
    npm i postcss-pxtorem autoprefixer postcss-loader postcss -D
    
    const HtmlWebpackPlugin = require("html-webpack-plugin");
    const path = require("path");
    
    module.exports = {
      entry: "./src/index.js",
      mode: "development",
      output: {
        filename: "[name].[contenthash].bundle.js",
        path: path.resolve("./dist"),
      },
      module: {
        rules: [
          {
            test: /\.css$/i,
            use: ["style-loader", "css-loader", "postcss-loader"],
          },
        ],
      },
      plugins: [
        new HtmlWebpackPlugin({
          template: "./index.html",
        }),
      ],
    };
    
    

    配置 postcss.config.js 文件,postcss-pxtorem 的配置 可以查询 文档

    module.exports = {
      plugins: {
        autoprefixer: {},
        "postcss-pxtorem": {
          rootValue: 80, // 根元素的字体大小
          unitPrecision: 5, // 小数点后精度
          propList: ["*"], // 可以从px改变为rem的属性
          exclude: /node_modules/i, // 要忽略并保留为px的文件路径
          minPixelValue: 0, // 最小的px转化值(小于这个值的不转化)
          mediaQuery: false, //  允许在媒体查询中转换px
          selectorBlackList: [], // 要忽略并保留为px的选择器
          replace: true, // 直接在css规则上替换值而不是添加备用
        },
      },
    };
    

    main.js 中引入lib_flexible.js index.js index.css ,最后重启项目即可。

这里我为了回顾一下 webpack 配置,就从 0 开始配置了。一般通过脚手架创建的项目会有集成webpack以及postcss的,只需要 安装一下 postcss postcss-pxtorem 与配置 postcss.config.js 即可

由于 viewport 单位得到众多浏览器的兼容,lib-flexible 这个过渡方案已经可以放弃使用,不管是现在的版本还是以前的版本,都存有一定的问题。下面就将介绍 viewport 的方案。

2. 适配方案2:vw 单位

直接使用 vw 单位。

屏幕的宽默认为 100vw,那么100vw = 1920px, 1vw = 19.2px 。

实现

pxvw

  • cssrem 插件方式转换

    image.png

    接着就可以按照 1920px * 1080px 的设计稿愉快开发,此时的页面已经是响应式,并宽高比不变

    image.png

  • webpack 插件转换

安装

npm i webpack webpack-cli -D
npm i style-loader css-loader html-webpack-plugin -D
npm i postcss-px-to-viewport autoprefixer postcss-loader postcss -D

webpack.config.js 配置不变

配置 postcss.config.js

module.exports = {
  plugins: {
    '@our-patches/postcss-px-to-viewport': {
      unitToConvert: 'px', // 要转化的单位
      viewportWidth: 1920, // UI设计稿的宽度
      unitPrecision: 6, // 转换后的精度,即小数点位数
      propList: ['*'], // 指定转换的css属性的单位,*代表全部css属性的单位都进行转换
      viewportUnit: 'vw', // 指定需要转换成的视窗单位,默认vw
      fontViewportUnit: 'vw', // 指定字体需要转换成的视窗单位,默认vw
      selectorBlackList: [], // 指定不转换为视窗单位的类名,
      minPixelValue: 1, // 默认值1,小于或等于1px则不进行转换
      mediaQuery: true, // 是否在媒体查询的css代码中也进行转换,默认false
      replace: true, // 是否转换后直接更换属性值
      include: /\/src\/views\/pc\/layoutMapBS\//,
      exclude: [/node_modules/], // 设置忽略文件,用正则做目录名匹配
      landscape: false // 是否处理横屏情况
    }
  }
}

:::warning{title="注意"} postcss-pxtoviewport 这个插件在文档中有 include 这个选项,但是作者一直没更新代码,导致这个选项一直无效,而且作者已经很久没改了。可以使用 @our-patches/postcss-px-to-viewport

安装

npm i @our-patches/postcss-px-to-viewport -D

配置 只需要在 postcss.config.js 中将 postcss-px-to-viewport 改为 postcss-px-to-viewport 即可 :::

3. 适配方案3:scale(推荐)

使用CSS3中的scale函数来缩放网页,这里我们将使用两种方案来实现:

  1. 方案一:直接根据宽度的比率进行缩放。(宽度比率=网页当前宽 / 设计稿宽)
<script>
window.onload = function () {
  triggerScale();
  window.addEventListener("resize", function () {
    triggerScale();
  });
};

function triggerScale() {
  var targetX = 1920;
  var targetY = 1080;

  // 获取html的宽度和高度(不包含滚动条)
  var currentX =
    document.documentElement.clientWidth || document.body.clientWidth;
  // https://developer.mozilla.org/en-US/docs/Web/API/Element/clientWidth
  var currentY =
    document.documentElement.clientHeight || document.body.clientHeight;

  // 1.缩放比例  3840 / 2160 => 2
  var ratio = currentX / targetX;

  var bodyEl = document.querySelector("body");
  // 2.需要修改缩放的原点 body { transform-origin: left top; }
  bodyEl.setAttribute("style", `transform:scale(${ratio})`);
}
</script>
  1. 方案二:动态计算网页宽高比,决定是是否按照宽度的比率进行缩放。
<script>
window.onload = function () {
  triggerScale();
  window.addEventListener("resize", function () {
    triggerScale();
  });
};

function triggerScale() {
  var targetX = 1920;
  var targetY = 1080;
  var targetRatio = 16 / 9;
  var currentX =
    document.documentElement.clientWidth || document.body.clientWidth;
  var currentY =
    document.documentElement.clientHeight || document.body.clientHeight;

  // 1.缩放比例  3840 / 2160 => 2
  var ratio = currentX / targetX;
  var currentRatio = currentX / currentY;
  var transformStr = "";
  if (currentRatio > targetRatio) {
    ratio = currentY / targetY;
    transformStr = `transform:scale(${ratio}) translateX(-${
      targetX / 2
    }px); left:50%;`;
  } else {
    transformStr = `transform:scale(${ratio})`;
  }
  var bodyEl = document.querySelector("body");
  // 2.需要修改缩放的原点 body { transform-origin: left top; }
  bodyEl.setAttribute("style", transformStr);
}
</script>

3. Vue3 hooks封装 useScalePage

import { onMounted, onUnmounted } from 'vue';
import _ from 'lodash' 

/**
  大屏适配的 hooks
 */
export default function useScalePage(option) {

  const resizeFunc = _.throttle(function() {
    triggerScale() // 动画缩放网页
  }, 100)

  onMounted(()=>{
    triggerScale()  // 动画缩放网页
    window.addEventListener('resize', resizeFunc)
  })

  onUnmounted(()=>{
    window.removeEventListener('resize', resizeFunc) // 释放
  })

  // 大屏的适配
  function triggerScale() {
    // 1.设计稿的尺寸
    let targetX = option.targetX ||  1920
    let targetY = option.targetY || 1080
    let targetRatio = option.targetRatio ||  16 / 9 // 宽高比率

    // 2.拿到当前设备(浏览器)的宽度
    let currentX = document.documentElement.clientWidth || document.body.clientWidth
    let currentY = document.documentElement.clientHeight || document.body.clientHeight

    // 3.计算缩放比例
    let scaleRatio = currentX / targetX; // 参照宽度进行缩放 ( 默认情况 )
    let currentRatio = currentX / currentY // 宽高比率

    // 超宽屏
    if(currentRatio > targetRatio) {
      // 4.开始缩放网页
      scaleRatio = currentY / targetY // 参照高度进行缩放
      document.body.style = `width:${targetX}px; height:${targetY}px;transform: scale(${scaleRatio}) translateX(-50%); left: 50%`
    } else {
      // 4.开始缩放网页
      document.body.style = `width:${targetX}px; height:${targetY}px; transform: scale(${scaleRatio})`
    }
  }
}

4. 总结

三种适配方案的对比

  • vw 相比于 rem 的优势
    • 优势一:不需要去计算 htmlfont-size 大小,不需要给 html 设置 font-size,也不需要设置 bodyfont-size ,防止继承;
    • 优势二:因为不依赖 font-size 的尺寸,所以不用担心某些原因 htmlfont-size 尺寸被篡改,页面尺寸混乱;
    • 优势三vw 相比于 rem 更加语义化1vw1/100viewport 大小(即将屏幕分成 100 份); 并且具备 rem 之前所有的优点
  • vwrem 存在问题
    • 如果使用 remvw 单位时,在 JS 中添加样式时,单位需要手动设置 remvw
    • 第三方库的字体等默认的都是 px 单位,比如:elementecharts,因此通常需要层叠第三方库的样式。
    • 当大屏比例更大时,有些字体还需要相应的调整字号
  • scale 相比 vwrem 的优势
    • 优势一:相比于 vwrem,使用起来更加简单,不需要对单位进行转换。
    • 优势二:因为不需要对单位进行转换,在使用第三方库时,不需要考虑单位转换问题。
    • 优势三:由于浏览器的字体默认最小是不能小于 12px ,导致 remvw 无法设置小于 12 px的字体,缩放没有这个问题。

附送250套精选项目源码

源码截图

 源码获取:关注公众号「码农园区」,回复 【源码】,即可获取全套源码下载链接

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

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

相关文章

大模型上下文实验之大海捞针和数星星

大模型上下文实验之大海捞针和数星星 大海捞针和数星星大海捞针大海捞针测试简介Greg Kamradt 的“大海捞针”实验实验步骤实验预期 ChatGPT-4 128K的实验结果Claude-2.1 200K的实验结果 数星星数星星简介多证据获取多证据推理 实验结果多证据获取任务示例多证据推理任务示例 数…

Adobe Premiere 视频编辑软件下载安装,pr 全系列资源分享!

Adobe Premiere以其强大的功能、灵活的操作和卓越的性能&#xff0c;成为视频编辑领域的佼佼者。 在剪辑方面&#xff0c;Adobe Premiere提供了强大而灵活的工具集。用户可以在直观的时间线上对视频进行精细的裁剪、剪辑和合并操作。无论是快速剪辑短片&#xff0c;还是精心打造…

洗地机哪个品牌比较好?四款好用靠谱的优质洗地机推荐

随着现代生活节奏的加快&#xff0c;家庭清洁成了一项耗时且繁琐的任务。洗地机凭借其智能化和高效的清洁能力&#xff0c;越来越受到大家的青睐。然而&#xff0c;市场上各种品牌和型号琳琅满目&#xff0c;让人眼花缭乱。为了帮助大家在众多选择中找到心仪的产品&#xff0c;…

真人模特+虚拟模特:阿里通义万相带你体验全新的卖家秀!

哈喽&#xff0c;大家好&#xff0c;我是木头左&#xff0c;致力于程序服务生活&#xff01; 一、引言 在数字化和虚拟化的时代&#xff0c;正在经历一场由人工智能驱动的革命。这场革命不仅改变了的生活&#xff0c;也正在改变的商业环境。阿里巴巴集团是这场革命的重要参与者…

铁路定向声波冲击波智能驱鸟器

对于铁路系统来说&#xff0c;鸟类活动会带来潜在的安全隐患。铁路沿线的接触网、电杆等设备&#xff0c;是鸟类筑巢的理想场所&#xff0c;但鸟类在筑巢过程中&#xff0c;常常使用的树枝、铁丝等杂物&#xff0c;一旦掉落在接触网设备上&#xff0c;就可能造成带电体与接地侧…

6月19日(周三)A股行情总结:A股震荡收跌,恒生科技指数大涨3%,10年期国债期货转涨续创新高

内容提要 车路云概念延续昨日涨势&#xff0c;华铭智能20CM 3连板。贵金属及PEEK材料概念全日走强&#xff1b;港股有色金属及能源股走强&#xff0c;紫金矿业涨超3%&#xff0c;中石油涨超3%。国债期货午后全线转涨&#xff0c;10年期主力合约涨0.05%报104.925元&#xff0c;…

2024年一年一度的618正式结束了,苹果与华为手机销量看看谁是大赢家?

一年一度的618正式结束了&#xff0c;各品牌基本上都发布了相应的战报。但是要告诉大家一点看战报要看定语&#xff0c;定语最少的才是真正的第一。现在给大家汇总下京东平台的数据&#xff0c;看看谁是最大赢家&#xff0c;谁又是国产荣光。注&#xff1a;所有数据截至6月18日…

好用的linux一键换源脚本

最近发现一个好用的linux一键换源脚本&#xff0c;记录一下 官方链接 大陆使用 bash <(curl -sSL https://linuxmirrors.cn/main.sh)# github地址 bash <(curl -sSL https://raw.githubusercontent.com/SuperManito/LinuxMirrors/main/ChangeMirrors.sh) # gitee地址 …

C语言练习01-循环

一、打印五行五列的三角形 如下图&#xff1a; #include<stdio.h>int main() {for (int i 1;i < 5; i){for (int j i; j < 5; j){printf("*");}printf("\n");}return 0; }#include<stdio.h>int main() {for (int i 1;i < 5; i){f…

鸿蒙开发通信与连接:【@ohos.bluetooth (蓝牙)】

蓝牙 说明&#xff1a; 本模块首批接口从API version 7开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 蓝牙模块提供了基础的传统蓝牙能力以及BLE的扫描、广播等功能。 导入模块 import bluetooth from ohos.bluetooth;bluetooth.enableBluet…

6.S081的Lab学习——Lab7: Multithreading

文章目录 前言一、Uthread: switching between threads (moderate)提示&#xff1a;解析 二、Using threads (moderate)解析&#xff1a; 三、Barrier (moderate)解析&#xff1a; 总结 前言 一个本硕双非的小菜鸡&#xff0c;备战24年秋招。打算尝试6.S081&#xff0c;将它的…

讨论字符串(未完)

讨论字符串 C语言中的字符串C中的字符串string类的构造函数string类对象的容量操作string类对象元素访问及遍历迭代器 string类对象的修改操作 string类的模拟实现成员变量构造函数析构函数扩容/预留空间push_back遍历operator[]迭代器 append任意位置插入数据和删除数据查找元…

PID控制算法学习笔记分享

目录 一、参数设定 二、PID计算公式 三、位置式PID代码实现 四、增量式PID代码实现 五、两种控制算法的优缺点 六、PID算法的改进 一、参数设定 比例系数&#xff08;kp&#xff09;&#xff1a;P项的作用是根据当前误差的大小来产生一个控制量。它直接与误差成正比&#…

Tensorflow入门实战 T05-运动鞋识别

目录 一、完整代码 二、训练过程 &#xff08;1&#xff09;打印2行10列的数据。 &#xff08;2&#xff09;查看数据集中的一张图片 &#xff08;3&#xff09;训练过程&#xff08;训练50个epoch&#xff09; &#xff08;4&#xff09;训练结果的精确度 三、遇到的问…

0618,0619 ,指针,指针与数组,字符串

目录 第八章&#xff08;指针&#xff09;&#xff0c;第九章&#xff08;指针和数组&#xff09;&#xff0c;第十章&#xff08;字符串&#xff09;思维导图 作业1 逆序打印 解答&#xff1a; 答案&#xff1a; 作业2 判断回文 解答&#xff1a; 答案&#xff1a; …

PCB设计隐藏的陷进

1、BGA芯片的开窗和过油设计。 加工工艺中&#xff0c;范式过孔都需要盖油设计&#xff0c;实心焊盘需要开窗设计&#xff0c;坚决不能盖油。 2、通孔设计的互联连通性 比如H3芯片的wifi设计&#xff0c;实际上是没有联通的&#xff0c;虽然四层板的中间层有焊盘&#xff0c;但…

【C++ | 移动构造函数】C++11的 移动构造函数 详解及例子代码

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; ⏰发布时间⏰&#xff1a;2024-06-12 2…

Mamaba3--RNN、状态方程、勒让德多项式

Mamaba3–RNN、状态方程、勒让德多项式 一、简单回顾 在Mamba1和Mamba2中分别介绍了RNN和状态方程。 下面从两个图和两个公式出发&#xff0c;对RNN和状态方程做简单的回顾&#xff1a; R N N : s t W s t − 1 U x t &#xff1b; O t V s t RNN: s_t Ws_{t-1}Ux_t&…

前字节员工自爆:我原腾讯一哥们,跳槽去小公司做小领导,就签了竞业,又从小公司离职去了对手公司,结果被发现了,小公司要他赔80万

“世界那么大&#xff0c;我想去看看”&#xff0c;这句曾经火遍网络的辞职宣言&#xff0c;说出了多少职场人心中的渴望。然而&#xff0c;当我们真的迈出跳槽那一步时&#xff0c;才发现&#xff0c;现实远比想象中残酷得多。 最近&#xff0c;一起前字节跳动员工爆料的事件…

22种常用设计模式示例代码

文章目录 创建型模式结构型模式行为模式 仓库地址https://github.com/Xiamu-ssr/DesignPatternsPractice 参考教程 refactoringguru设计模式-目录 创建型模式 软件包复杂度流行度工厂方法factorymethod❄️⭐️⭐️⭐️抽象工厂abstractfactory❄️❄️⭐️⭐️⭐️生成器bui…