大屏适配方案汇总

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 字体大小默认为 16pxdocument.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 = 80docEl.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, //  允许在媒体查询中转换pxselectorBlackList: [], // 要忽略并保留为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', // 指定需要转换成的视窗单位,默认vwfontViewportUnit: 'vw', // 指定字体需要转换成的视窗单位,默认vwselectorBlackList: [], // 指定不转换为视窗单位的类名,minPixelValue: 1, // 默认值1,小于或等于1px则不进行转换mediaQuery: true, // 是否在媒体查询的css代码中也进行转换,默认falsereplace: 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/clientWidthvar currentY =document.documentElement.clientHeight || document.body.clientHeight;// 1.缩放比例  3840 / 2160 => 2var 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 => 2var 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 ||  1920let targetY = option.targetY || 1080let targetRatio = option.targetRatio ||  16 / 9 // 宽高比率// 2.拿到当前设备(浏览器)的宽度let currentX = document.documentElement.clientWidth || document.body.clientWidthlet 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.mzph.cn/web/30104.shtml

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

相关文章

制作一个苹果软件自动运行工具需要用到的源代码!

在数字化时代的浪潮中&#xff0c;自动化运行工具扮演着越来越重要的角色&#xff0c;这些工具可以极大地提高工作效率&#xff0c;减少人为操作的繁琐和错误。 在苹果软件生态系统中&#xff0c;制作一个自动运行工具同样具有广泛的应用前景&#xff0c;本文将围绕“制作一个…

模拟原神圣遗物系统-小森设计项目,需求分析

需求分析 我操控某个角色的圣遗物时发现&#xff0c;一开始玩啥也不懂慢慢了解&#xff0c;今天才想起要不做一个 &#xff0c;然后开始想需求 跟Ai聊技术 聊着聊着 发现圣遗物 这个东西有点意思 本来今天打算写一下数据库 的外键想起了一些高兴的事情&#xff08;美人鱼&#…

C# WinForm —— 36 布局控件 GroupBox 和 Panel

1. 简介 两个可以盛放其他控件的容器&#xff0c;可以用于把不同的控件分组&#xff0c;一般不会注册事件 GroupBox&#xff1a;为其他控件提供可识别的分组。可通过Text属性设置标题&#xff1b;有边框&#xff1b;没有滚动条&#xff0c;一般用于按功能分组 Panel&#xff…

SpringBoot+Maven项目的配置构建

文章目录 1、application.properties2、pom.xml 1、application.properties 也可使用yml yaml #静态资源 spring.mvc.static-path-pattern/images/** #上传文件大小设置 spring.http.multipart.max-file-size10MB spring.http.multipart.max-request-size10MBspring.mvc.path…

Sui的Fastcrypto加密库刷新速度记录

Sui使用的加密库Fastcrypto打破了许多速度记录&#xff0c;Mysten Labs在基准测试和安全分析中的工作修复了许多安全漏洞&#xff0c;同时通过识别新的优化技巧为创新开辟了道路。 最近在伦敦帝国理工学院举行的国际性能工程会议&#xff08;ICPE&#xff09;基准测试研讨会上…

【LeetCode:394. 字符串解码 + 栈 | 递归】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

智慧路灯:照亮未来城市的智慧之光

智慧路灯&#xff0c;顾名思义&#xff0c;是在传统路灯基础上集成物联网、大数据、云计算、人工智能等现代信息技术的新型照明系统。它不仅提供节能高效的照明服务&#xff0c;更成为城市信息采集、传输、发布的载体&#xff0c;以及多种增值服务的平台。 核心功能与技术创新 …

聊聊 Mybatis 动态 SQL

这篇文章&#xff0c;我们聊聊 Mybatis 动态 SQL &#xff0c;以及我对于编程技巧的几点思考 &#xff0c;希望对大家有所启发。 1 什么是 Mybatis 动态SQL 如果你使用过 JDBC 或其它类似的框架&#xff0c;你应该能理解根据不同条件拼接 SQL 语句有多痛苦&#xff0c;例如拼…

如何设置文件夹密码?文件夹加密如何操作!分享4款安全加密软件!

在数字化时代&#xff0c;数据安全显得尤为重要。设置文件夹密码和加密操作是保护个人或企业数据不被非法访问的有效手段。本文将为您详细介绍如何设置文件夹密码和加密操作&#xff0c;并分享四款安全加密软件&#xff0c;助您轻松提升数据安全防护能力。 一、如何设置文件夹/…

工作人员能从轧钢测径仪上获取哪些有效信息?

轧钢测径仪安装在轧钢生产线中&#xff0c;无论是热轧还是冷轧&#xff0c;都不能阻挡测径仪的高速无损高精检测。它采用八轴测量系统&#xff0c;能全方位检测外径尺寸&#xff0c;并且配备了测控软件系统&#xff0c;为工作人员提供更加丰富的产线信息。 普通轧钢测径仪能获…

Playwright 入门教程

1. 环境说明 操作系统&#xff1a;macOS 11.7Python&#xff1a;3.10.6 2. 安装 2.1. 创建测试环境 mkdir playwright-demo cd playwright-demo/ python3 -m venv venv # 安装 Pytest 插件 venv/bin/pip3 install pytest-playwright # 安装需要的浏览器 venv/bin/playwrigh…

DLP数据防泄密系统有什么功能?四款特别好用的DLP仿泄密系统

DLP&#xff08;Data Loss Prevention&#xff0c;数据丢失防护&#xff09;系统是一类专门用于保护组织内部数据不被非法访问、泄露或误用的安全解决方案。 这类系统通常具备以下关键功能&#xff1a; 1.数据识别与分类&#xff1a;自动发现并分类存储在网络、终端和云环境中…

24计算机应届生的活路是什么

不够大胆❗ 很多小伙伴在找工作时觉得自己没有竞争力&#xff0c;很没有自信&#xff0c;以至于很害怕找工作面试&#xff0c;被人否定的感觉很不好受。 其实很多工作并没有想象中的高大上&#xff0c;不要害怕&#xff0c;计算机就业的方向是真的广&#xff0c;不要走窄了&…

朋友圈新功能:实现定时发圈,自动跟圈

1.多号同时发圈 可以选择多个号同时发圈&#xff0c;提高工作效率。 2.定时发布 可以一次性设置完很多天的朋友圈&#xff0c;选好发送时间就可以解放双手。 3.一键转发 点击转发&#xff0c;可直接跳转到编辑页面。无需复制粘贴。 4.自动转发&#xff08;跟圈&#xff09; …

机能学实验通过ZL-620C一体化信息化生物信号采集系统具体呈现

ZL-621大屏教学试教系统为了实施机能学实验的教学改革&#xff0c;大力减轻教师的实验教学负担&#xff0c;主要功能电子白板&#xff0c;同步教学、控制、过程仿真、虚拟现实、三维动画、管理、音视频广播、PPT教材等于一体&#xff0c;大屏教学试教系统并能同时实现屏幕监视和…

湖北文理学院2024年成人高等继续教育招生简章

湖北文理学院&#xff0c;作为一所历史悠久、底蕴深厚的学府&#xff0c;始终致力于为社会各界培养具备高素质、专业技能和创新精神的优秀人才。在成人高等继续教育领域&#xff0c;湖北文理学院更是凭借其卓越的教学质量和丰富的教育资源&#xff0c;吸引了众多有志于提升自身…

Cesium入门学习(一)

下载cesium源代码 安装依赖 npm install注册账户&#xff0c;申请一个token 没有这个token&#xff0c;会导致地图中只能看到一个宇宙&#xff0c;没有办法看到地球 cesium的官网&#xff1a;cesium官网 替换token 替换对应位置的token 启动 运行 npm run build npm r…

72. UE5 RPG 实现召唤技能数量的限制,并优化技能相关

在上一篇文章里&#xff0c;我们实现了召唤技能&#xff0c;并且能够无限的召唤。所以&#xff0c;这属于一个bug&#xff0c;我们不能无限制的去召唤&#xff0c;这会影响游戏的体验。所以&#xff0c;在这篇里面&#xff0c;我们实现一下对召唤物数量的限制&#xff0c;并优化…

华为---- RIP路由协议基本配置

08、RIP 8.1 RIP路由协议基本配置 8.1.1 原理概述 RIP(Routing Information Protocol,路由协议)作为最早的距离矢量IP路由协议&#xff0c;也是最先得到广泛使用的一种路由协议&#xff0c;采用了Bellman-Ford算法&#xff0c;其最大的特点就是配置简单。 RIP协议要求网络中…