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

2023-11-09

为什么需要适配

目前市面上设备屏幕属性十分多样化(宽度和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 || 1

      document.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页面适配方案

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

不同设备屏幕尺寸和DPR适配 的相关文章

  • 引导标签输入宽度

    我正在尝试使用引导程序标签输入 http timschlechter github io bootstrap tagsinput examples 以模态中包含的形式 像这样 div class form group div
  • 使 Material UI Grid 项目的子项拉伸以适合父容器的剩余高度

    1 现状 我有一个包含 4 个网格项的 Material UI 网格容器 每个 Grid 项中都有一个 Typography 组件 其中包含标题和包含一些内容的 Card 如下所示 2 期望的外观 我希望卡片填充网格项目的剩余高度并且不超过
  • 将父容器扩展至 100% 高度以容纳浮动内容

    我正在为一个客户项目而苦苦挣扎 我的全部divs 没有绝对定位 height 100 for html body 和容器divs 但静态内容未达到其内容 在 910 像素处 我可以将溢出属性更改为auto 并且背景会继续向下到内容的末尾 但
  • 增加数字输入、CSS、HTML 上的向下和向上箭头的大小

    有没有办法利用CSS来增大数字输入框右侧的上下箭头的大小 只是向上和向下箭头 而不是整个输入框 或者至少是按比例的 看这个例子 size 36 font size 36px size 12 font size 12px
  • Textmate“注释”命令对于 css 代码无法正常工作

    当我在 TextMate 中切换 CSS 源代码的注释时遇到一些问题 Using the shortcut CMD I activate the Comment Line Selection command from the source
  • 如何将此 HTML 表格布局解决方案转换为浮动 div 解决方案?

    我经常需要列出各种尺寸的项目images在左边和text在右边 像这样 替代文本 http www deviantsart com upload 7s01l5 png http www deviantsart com upload 7s01
  • 如何将送货地址复制到帐单地址

    我想知道是否可以将送货地址复制到帐单地址 当用户单击与送货地址相同的复选框时 送货地址值将被复制到账单输入字段 我完成了大部分部分 但我不确定如何将选择菜单 状态 值复制到帐单地址 我真的很感谢任何帮助 My code document r
  • 覆盖并重置 CSS 样式:auto 或 none 不起作用

    我想覆盖为所有表定义的以下 CSS 样式 table font size 12px width 100 min width 400px display inline table 我有一个特定的表 其类名为 other 最后的餐桌装饰应该是这
  • Twitter 嵌入时间轴小部件

    我继续下载http platform twitter com widgets js http platform twitter com widgets js And the http platform twitter com embed t
  • 为范围旋钮 ionic-range 添加边框颜色

    我正在使用离子范围添加范围滑块 并想向范围旋钮添加边框 由于它的 ionic4 和范围旋钮是 Shadow dom 的一部分 我无法使用范围旋钮的 border 属性直接更改边框 我已附上我想要实现的图像 范围旋钮周围有白色边框 现有属性只
  • 绝对定位的 div 中的文本重叠

    在下面的代码片段中 div 元素 main gt div 相对定位并向左浮动 由于相对定位 div 元素 main gt div 彼此相邻放置 span 元素位于 div 元素下方 main gt div gt span span 元素绝对
  • 如何在悬停标签时显示块div

    如何在悬停标签时打开 div 标签 服务是标签的id services是div标签的id 我的 HTML 代码是 ul li a href Services a li ul div h1 Hello h1 div 我的CSS代码是这样的 S
  • Overflow:auto 导致子 DIV 的绝对元素消失

    我有一个 div A 我在其中设置了overflow auto 现在在该 div 内 我有两个 div 父 div B 设置为position relative和子 div C 是position absolute 现在的问题是 设置ove
  • 滚动时我的身体背景颜色消失

    我希望有人能帮帮忙 我已将 body height 属性设置为 100 当所有内容同时显示在屏幕上时 这很好 然而 当我需要滚动 最小化窗口时 主体颜色消失 只留下我为 HTML 背景设置的颜色 有人知道解决办法吗 html backgro
  • 水平滚动条仅出现在页面底部

    我有一个具有以下 HTML 结构的页面 div class wrapper div The wrapper被设置为min width 1100px至于原因我就不多说了 因此 当浏览器大小调整为小于 1100px 时 我希望出现水平滚动条 我
  • 双弧形

    我目前正在尝试生成 波浪形幽灵底部 形状 该形状包含两条双曲线 虽然底部的部分这个图片 http images clipartpanda com ghost clip art castle ghost clipart1 jpg我认为以更好的
  • 如何使 WordPress 主题全宽?

    我尽了最大努力 但无法通过编辑 CSS 使以下主题全宽 屏幕 如果您能向我展示或给我有关此定制的提示 我将不胜感激 http demo mythemeshop com sociallyviral http demo mythemeshop
  • 角度 2 中的动态 styleUrls?

    是否可以将样式表的 url 动态注入到组件中 就像是 styleUrls stylesheet1 css this additionalUrls 或者 一厢情愿并注意这只是假代码 export class MyComponent imple
  • jquery:当我在文档上附加一层时,如何重置文档滚动条?

    当我在文档上附加图层时 如何重置文档滚动条 例如 它就像 Facebook 页面 当您有一个很长的文档时 您需要向下滚动才能查看较旧的图像 帖子 当你点击照片时 滚动条发生了变化 从顶部开始 但文档页面根本不跳转 当关闭照片查看器图层时 滚
  • CSS - 第一个没有特定类别的孩子

    是否可以编写一个 CSS 规则来选择没有特定类的元素的第一个子元素 example div span class common class ignore span span class common class ignore span sp

随机推荐

  • Java中的while循环

    Java中的while循环和do while循环 开发工具与关键技术 Java 作者 黄瑞杰 撰写时间 2022 11 18 while循环 while是最基本的循环 1 格式 只要布尔表达式为 true 循环就会一直执行下去 练习1 打印
  • python统计正数负数的个数

    方法一 encoding utf 8 original list 1 3 5 7 0 1 9 4 5 8 positive list negative list for i in original list if i gt 0 positi
  • linux里面touch 和 mkdir

    一 touch命令 touch命令有两个作用 一个是创建新的空文件 二是用于把已存在的文件的时间标签更新为系统当前的时间 默认方式 它们的数据将原封不动地保留下来 语法 touch options filename a 改变访问时间 m 改
  • 竞品还在追赶 OpenAI用GPT-4飚赢自己

    赶在百度 文心一言 发布前一天 OpenAI祭出了GPT 4 这对于百度 谷歌们来说 可能是一个重大打击 人们已经领略过GPT 3 5加持下的ChatGPT 但GPT 4比 前辈 更强大 它具有更高的可靠性和准确性 能够读懂图片 甚至还能角
  • Android平滑移动——Scroller类研究,太厉害了

    2 computeScrollOffset 方法 public boolean computeScrollOffset if mFinished return false int timePassed int AnimationUtils
  • 入门Python数据分析最好的实战项目 分析篇

    目的 本篇给大家介绍一个数据分析的初级项目 目的是通过项目了解如何使用Python进行简单的数据分析 数据源 博主通过爬虫采集的链家全网北京二手房数据 文末 可获取 数据初探 首先导入要使用的科学计算包numpy pandas 可视化mat
  • 云计算学习总结

    云计算总结 理论汇总 与saas不同 基于平台服务的云计算形式把开发环境或者运行平台也作为一种服务给用户提供 云计算是对并行计算 网格计算 分布式计算技术的发展与运用 Amazon com公司通过EC2计算云 可以让客户通过webservi
  • WPF 折线图

    一 折线图 一 安装和查看值 1 需要联网安装 通过Nuget安装LiveCharts 搜索安装 2 想查看需要使用的值 点击对象管理器 查LiveCharts Wpf Series 里面有需要用的值 安装完成的效果 二 视图代码
  • List多字段升降序排序

    工具类 Component public class SortListUtil
  • 【Unity笔记】获得鼠标点击屏幕的位置,并转成世界坐标

    Vector3 pos Camera main ScreenToWorldPoint Input mousePosition
  • Win 10 设置右键以管理员方式打开 CMD 窗口

    Add Open Command Window Here as Administrator reg Windows Registry Editor Version 5 00 HKEY CLASSES ROOT Directory shell
  • [623]64位WIN10下安装.net20

    下载Microsoft NET Framework 2 0 软件开发工具包 SDK x64 地址 https www microsoft com zh CN download confirmation aspx id 15354 https
  • Ubuntu防火墙操作

    ubuntu默认提供了防火墙工具ufw 安装sudo apt get install ufw 检查防火墙的状态 sudo ufw status inactive 关闭 active 开启 关防火墙 sudo ufw disable 开防火墙
  • linux 全局查找文件命令

    find name xxx aaa
  • android bitmap面试题,Android面试Android进阶(十四)-Bitmap相关问题

    问 drawable和mipmap的区别是什么 答 根据官方说明 应用图标的图片资源存放在mipmap系列文件夹中 而其余图片存放在drawable系列文件夹中 1 mipmap纹理映射技术会将资源缩放到设备分辨率大小 drawable会将
  • Struts2框架xml验证

    struts2框架验证 xml方式 首先要从页面中获取对应的标签name属性的值 在动作类action中声明同名的属性 提供get和set方法 创建一个xml格式验证文件 命名方式 ActionClassName validation xm
  • vue2 + antd1.7.8 和 vue3 + antd2.2.8表单动态添加删除表单项

    1 vue2 antd 1
  • 英文投稿的一点经验【转载】

    英文投稿的一点经验 转载 1 首先一定要注意杂志的发表范围 超出范围的千万别投 要不就是浪费时间 另外 每个杂志都有他们的具体格式要求 一定要按照他们的要求把论文写好 免得浪费时间 前些时候 我的一个同事向一个著名的英文杂志投稿 由于格式问
  • 【Android App】实战项目之仿微信的私信和群聊App(附源码和演示视频 超详细必看)

    需要全部代码请点赞关注收藏后评论区留言私信 手机最开始用于通话 后来增加了短信功能 初步满足了人与人之间的沟通需求 然而短信只能发文字 于是出现了能够发图片的彩信 但不管短信还是彩信 资费都太贵了 令人惜墨如金 后来移动公司推出飞信 它支持
  • 不同设备屏幕尺寸和DPR适配

    为什么需要适配 目前市面上设备屏幕属性十分多样化 宽度和DPR并不一致 而作为设计和前端开发 无法为每个尺寸的设备单独设计一套UI并将其转为前端代码 这不现实 所以我们需要一套方案来将一套设计稿完美呈现在不同尺寸的设备上 设备的多样性不止体