不同设备屏幕尺寸和DPR适配

为什么需要适配

目前市面上设备屏幕属性十分多样化(宽度和DPR并不一致),而作为设计和前端开发,无法为每个尺寸的设备单独设计一套UI并将其转为前端代码,这不现实。所以我们需要一套方案来将一套设计稿完美呈现在不同尺寸的设备上。
设备的多样性不止体现在设备屏幕尺寸上,还有屏幕的DPR也不同,有1,有2,有3等等。不同DPR的设备展示的视图清晰度也不同,所以这套方案要考虑屏幕尺寸和屏幕清晰度这两个因素。

一些基本概念

一个屏幕的DPR是根据屏幕的物理像素除以屏幕的设备独立像素(也叫密度无关像素)得来的(DPR = 物理像素 / 设备独立像素)。iphone6宽度的设备独立像素是375,宽度的物理像素是750,那么就意味着DPR是2。这就意味着需要四个物理像素来描绘一个设备独立像素,就像一个(请忽略边框)的形状。

设备独立像素又叫做密度无关像素,可以认为是系统中一个点,这个点可以是可以由程序使用的虚拟像素(如CSS的px),然后系统会将这个像素转换为物理像素,在屏幕的DPR为2的设备上CSS的1px就会转为4个物理像素

屏幕密度(PPI),通常是计算每英寸有多少个像素(设备独立像素),计算公式是:屏幕斜对角的像素数除以屏幕的英寸得出PPI的值。

对一开始适配问题做出一定程度的解释

根据上面DPR解释可以知道在DPR为2的屏幕上会使用四个设备像素来描述一个CSS像素。在这种情况下一张100*100的图片在页面上的尺寸也是100*100那么其实是200*200个物理像素来描绘这张图片,很明显图片的像素是不够的,这时候系统就会让剩下的像素就近取色,这样就造成了图片的模糊,想要图片不模糊要么提供一个200*200的图片,要么将页面上100*100的容器缩小到50*50。

在DPR为2的屏幕上高度的1px其实是由2个物理像素描绘的,所以该屏幕可以描绘的最小像素应该是0.5px,所以这个1px应该是0.5px才对。

怎么做适配

既然提出了问题那么就需要解决,解决方案主要来自手淘的flexibleJS,其原理就是适配不同屏幕尺寸主要用到了rem,而适配不同的DPR主要用到了<meta name="viewport" content="initial-scale=1/dpr"/>

不同屏幕尺寸

在CSS中单位使用rem,那么只要修改html的font-size那么这个页面的尺寸都会随之等比例改变。例如:
首先我们知道设计稿宽度例如750px,其中有个100px的正方形
其次我们也知道当前运行代码的设备的屏幕宽度document.documentElement.clientWidth,这样就可以算出来在当前设备下这个正方形的宽高
在这里插入图片描述
通过观察上面设备下元素尺寸的计算公式 100px * document.documentElement.clientWidth / 750。可以简化成 设计稿元素尺寸 * 某个系数,可以联想到rem。这个单位后面的系数就是rem对应的font-size值。
所以在375屏幕尺寸下rem对应的font-size就是 375 / 750 等于 0.5px,0.5px * 100px 等于 50px。所以750下100单位在375设备下为50单位。
到这里我们得到公式 x = 元素在设计稿上的尺寸 * (设备宽度 / 设计稿宽度),其中 设备宽度 / 设计稿宽度是html的font-size值,也就是1rem。
但问题是浏览器有最小font-size的限制,目前算出来的1rem对于的font-size是0.5px,显然小于最小font-size的限制。
所以我们要将1rem对应的font-size搞大点,修改下公式:
x = (元素在设计稿上的尺寸 / 100) * ((设备宽度 / 设计稿宽度) * 100)
将1rem对应的font-size变大之后,要将其调整回来,需要对设计稿上的尺寸再缩小对应倍数。
到这里我们就完成了一份设计稿适配不同尺寸设备的方案。

<div class='container'>
</div>
<style>.container {width: 1rem; /* (100px / 100)rem */height: 1rem; /* (100px / 100)rem */}
</style>
<script>
document.querySelector('html').style = 'font-size: ' + document.documentElement.clientWidth / 750 /* 设计稿尺寸 */ * 100 /* 将1rem对应的font-size值放大 */) + 'px'
</script>

不同DPR

模糊主要是由于图片像素不够导致的,例如有一张100 * 100的图片需要渲染在200 * 200的盒子中,因为图片的10000个像素点需要铺满40000个像素的面积,就会导致图片渲染的有些模糊,这个问题可以通过切2~3倍图来解决。但是0.5像素的问题则需要使用页面缩放来解决,因为dpr2的设备上可以渲染出来0.5px,而逻辑像素最小是1px。
对于适配不同设备DPR的高清方案思路如下:

  1. 将整个页面的基础单位,也就是rem放大 DPR倍
  2. 使用meta name=“viewport” 将整个页面缩小到 1 / DPR

这样就可以保证一个物理像素对应一个逻辑像素,让整个画面看起来清晰很多。

function adapterHD (width = 750) {const dpr = window.devicePixelRatio || 1document.querySelector('meta[name="viewport"]').setAttribute("content", "width=device-width, initial-scale=" + 1 / dpr)const oneRem = Math.floor(document.documentElement.clientWidth / width * 100)document.querySelector('html').style = 'font-size: ' + (oneRem) + 'px'
}

因为首先设置了缩放,缩放后 documentElement.clientWidth就会放大 DPR倍,所以onRem没有显式乘以DPR。

到这里还有两个问题需要解决:

  1. html元素被设置font-size之后因为font-size属性可以继承,整个网站的font-size默认都会变的很大,所以需要在body元素上重置下font-size属性
  2. 因为默认的font-size需要乘以100,所以在CSS中我们需要将设计稿上的尺寸除以100并且转换成rem单位,这个事情开发者手动去做十分繁琐且容易出错,所以可以用下面提到的postcss插件完成

flexibleJS

在引用上文提到的手淘的flexibleJS之后会自动设置html的font-size为75px,这时候的主要问题就是怎么将设计稿(一般都是750*1334)中的各个px值转换为rem。可以自己手动算(比较麻烦),可以使用编辑器插件,使用postcss插件等详情见使用Flexible实现手淘H5页面的终端适配

参考

移动端H5页面高清多屏适配方案

使用Flexible实现手淘H5页面的终端适配

viewports剖析

再聊移动端页面的适配

移动端Web页面适配方案

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

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

相关文章

Edge浏览器开发人员工具

UserAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.10240" 本地存储/会话存储模拟达到上限 资源终于全部列表出来了 删除 Cookie 和 删除会话 Cookie 样式可以实时编辑了 …

linux 第一个内核模块Hello World

内核模块是Linux内核向外部提供的一个插口&#xff0c;其全称为动态可加载内核模块&#xff08;Loadable Kernel Module&#xff0c;LKM&#xff09;&#xff0c;我们简称为模块。Linux内核之所以提供模块机制&#xff0c;是因为它本身是一个单内核&#xff08;monolithic kern…

【JS复习笔记】00 序

作为一个前端苦手&#xff0c;说是复习&#xff0c;你就当我是重学好了。 好吧&#xff0c;我当然不可能抱着一个砖头去复习&#xff0c;所以捡了本薄的来读——《JavaScript语言精粹》。 当初带我的人说这本书挺好&#xff0c;就看这本书好了。我觉得他说的挺对。我喜欢这么…

Generator执行步骤浅析

在Generator函数出现之前JS的函数只能返回一个值&#xff0c;返回的方式就是return&#xff0c;但是Generator函数可以返回多个值&#xff0c;返回的方式是yield。并且Generator赋予了外部动态影响函数内部的执行顺序的能力。 基础语法 function* f () {const a yield 1cons…

使用 jQuery.Pin 垂直滚动时固定导航

ZKEACMS的导航默认是不能固定的&#xff0c;随着页面的滚动而滚动&#xff0c;为了有更好的用户体验&#xff0c;当页面往下滚动时&#xff0c;可以将导航固定在顶端&#xff0c;这样方便用户点击。 jQuery Pin 借助jQuery的一个插件 jQuery.Pin&#xff0c;这个插件可在用来…

MDK升级后的头文件冲突

////TITLE:// MDK升级后的头文件冲突//AUTHOR:// norains//DATE:// Friday 17-June-2011//Environment:// Keil MDK 4.2// .NET Micro Framework Porting 4.1// 因为在移植的时候&#xff0c;发现了不少MDK编译的一些问题&#xff0c;于是便想升级到最新版本&a…

阻止默认事件

在JS中经常需要阻止元素的默认事件。而阻止默认事件的方法都是使用事件对象的preventDefault()方法或者在函数中return false。在最近一次开发中使用preventDefault()方法的时候遇到一个问题&#xff0c;现在才想/猜明白原因&#xff0c;场景是这样的&#xff1a; <a href&…

MySQL之SQL优化详解(三)

目录 MySQL 之SQL优化详解&#xff08;三&#xff09; 1. 索引优化2. 剖析报告:Show ProfileMySQL 之SQL优化详解&#xff08;三&#xff09; 1. 索引优化 一旦建立索引&#xff0c;select 查询语句的where条件要尽量符合最佳左前缀的原则&#xff0c;如若能做到全值匹配最好。…

行内格式化

相对于熟知的块级格式化上下文&#xff0c;行内格式化上下文更加的复杂难明。行内元素不像块级元素那样直来直去&#xff0c;一个块级元素占据一行&#xff0c;其他块级元素在垂直方向依次向下排列即可。行内元素不同&#xff0c;多个行内元素可以在一行显示&#xff0c;那么&a…

[转载]struts+hibernate遇到的错误总结

原文地址&#xff1a;strutshibernate遇到的错误总结作者&#xff1a;畫上句號经过对strutshibernate几天的学习&#xff0c;大体上还算比较的了解机制&#xff0c;以前学习的时候都是 单个框架训练&#xff0c;没有结合2个框架做&#xff0c;所以今天就找了个网上发布租房信息…

JPA休眠替代方案。 如果JPA或Hibernate对于我的项目而言不够好,该怎么办?

你好&#xff01;你好吗&#xff1f; 今天&#xff0c;我们将讨论不建议使用JPA / Hibernate的情况。 在JPA领域之外&#xff0c;我们还有哪些选择&#xff1f; 我们将谈论的是&#xff1a; JPA /休眠问题 解决一些JPA /休眠问题的方法 选择此处描述的框架的标准 Spring J…

一个Web前端自学者的自述

想来想去还是写下这篇文章&#xff0c;先说明&#xff0c;我精通JAVA编程语言和web前端常见的技术&#xff0c;个人是做JAVA的多&#xff0c;但是更加喜欢前端。因为我从高一开始接触JAVA&#xff0c;家父是黑马的JAVA讲师&#xff0c;自己对编程很热爱&#xff0c;在大学的时候…

css实现web前端最美的loading加载动画!

这些好看的loading效果&#xff0c;你还只会用第三方库吗&#xff1f;CSS3教你实现 ​前言 loading效果在实际开发中是很常见的&#xff0c;尤其是在Ajax请求的时候&#xff0c;可以给用户一个很好的交互体验。 今天这篇文章我们一起来看看如何通过CSS3实现各种不同的loadin…

如何使用Hibernate从Play生成DDL脚本! 框架项目

好的&#xff0c;因此您一直在使用hibernate属性名称“ hibernate.hbm2ddl.auto ” value “ 更新 ”来不断更新数据库架构&#xff0c; 但是现在您需要一个完整的DDL脚本吗&#xff1f; 从您的Global Class onStart中使用此方法来导出DDL脚本。 只需为其提供实体的包名称&…

C# 设计模式,工厂方法

C#工厂方法 1 using System;2 using System.Collections.Generic;3 using System.Linq;4 using System.Text;5 using System.Threading.Tasks;6 7 namespace 工厂方法 {8 class Program {9 static void Main(string[] args) { 10 IFacotry i new Fact…

css3帮你轻松实现圆角效果,不一样的前端页面。

在Web前端页面实现圆角效果&#xff0c;CSS3帮你轻松实现&#xff0c;一个人人皆知的属性 圆角边框的绘制是Web页面和Web应用程序中经常用来美化页面效果的手法之一。今天&#xff0c;小编为大家介绍CSS3提供的可以将矩形变为圆角矩形的一个属性 技术等级&#xff1a;中级 | 适…

使用Vysper,TomEE和PrimeFaces将XMPP服务器嵌入JSF Web应用程序内部

我有一个需要在完成某些工作时通知用户的应用程序。 它使用JSF和Primefaces&#xff0c;因此可以使用大气 &#xff08;也称为Push&#xff09;来实现这种通知。 但是另一个有趣的方法是使用嵌入在Java Web应用程序中的XMPP服务器。 好的&#xff0c;好的&#xff0c;您不必嵌…

appium和selenium不同与相同之处

原文来自&#xff1a; https://www.cnblogs.com/zhengshuheng/p/6370398.html selenium是web端的自动化&#xff0c;appium是app端的自动化&#xff0c;它继承了webdriver(也就是selenium 2) 转载于:https://www.cnblogs.com/lv-lxz/p/11118862.html

使用 Visual Studio 编译 wget 为库文件

添加代码与预编译指令与上一篇使用 Visual Studio 编译 wget 为可执行文件一致&#xff0c;区别在于这回建的是静态库工程&#xff08;编译为动态库过程类似:)&#xff09; 从wget的main函数开始读下来&#xff0c;发现问题不少&#xff0c;程序可能基于效率或者编码方便的因素…

webpack中实现按需加载

当页面中一个文件过大并且还不一定用到的时候&#xff0c;我们希望在使用到的时候才开始加载这个文件俗称按需加载。这样可以减少页面的响应时间&#xff0c;提高访问速度。 使用webpack打包的出来的文件要实现以上的要求有两种方式&#xff0c;一个是webpack特有的require.en…