开云体育官网:关于移动端适配,你必须要知道的

作者:中国有限公司  时间:2023-03-17  浏览量:89707

本文摘要:导读移动端适配,是我们在开发中经常会遇到的,这内里可能会遇到很是多的问题:1px问题UI图完美适配方案iPhoneX适配方案横屏适配高清屏图片模糊问题...上面这些问题可能我们在开发中已经知道如何解决,可是问题发生的原理,以及解决方案的原理可能会模糊不清。

开云体育官网

导读移动端适配,是我们在开发中经常会遇到的,这内里可能会遇到很是多的问题:1px问题UI图完美适配方案iPhoneX适配方案横屏适配高清屏图片模糊问题...上面这些问题可能我们在开发中已经知道如何解决,可是问题发生的原理,以及解决方案的原理可能会模糊不清。在解决这些问题的历程中,我们往往会遇到很是多的观点:像素、分辨率、PPI、DPI、DP、DIP、DPR、视口等等,你真的能分清这些观点的意义吗?本文将从移动端适配的基础观点出发,探究移动端适配种种问题的解决方案和实现原理。

一、英寸一般用英寸形貌屏幕的物理巨细,如电脑显示器的17、22,手机显示器的4.8、5.7等使用的单元都是英寸。需要注意,上面的尺寸都是屏幕对角线的长度:英寸(inch,缩写为in)在荷兰语中的本意是大拇指,一英寸就是指甲底部普通人拇指的宽度。

英寸和厘米的换算:1英寸 = 2.54 厘米二、分辨率2.1 像素像素即一个小方块,它具有特定的位置和颜色。图片、电子屏幕(手机、电脑)就是由无数个具有特定颜色和特定位置的小方块拼接而成。像素可以作为图片或电子屏幕的最小组成单元。

下面我们使用sketch打开一张图片:将这些图片放大即可看到这些像素点:通常我们所说的分辨率有两种,屏幕分辨率和图像分辨率。2.2 屏幕分辨率屏幕分辨率指一个屏幕详细由几多个像素点组成。

下面是apple的官网上对手机分辨率的形貌:iPhone XS Max 和 iPhone SE的分辨率划分为2688 x 1242和1136 x 640。这表现手机划分在垂直和水平上所具有的像素点数。固然分辨率高不代表屏幕就清晰,屏幕的清晰水平还与尺寸有关。2.3 图像分辨率我们通常说的图片分辨率其实是指图片含有的像素数,好比一张图片的分辨率为800 x 400。

这表现图片划分在垂直和水平上所具有的像素点数为800和400。同一尺寸的图片,分辨率越高,图片越清晰。2.4 PPIPPI(Pixel Per Inch):每英寸包罗的像素数。

PPI可以用于形貌屏幕的清晰度以及一张图片的质量。使用PPI形貌图片时,PPI越高,图片质量越高,使用PPI形貌屏幕时,PPI越高,屏幕越清晰。在上面形貌手机分辨率的图片中,我们可以看到:iPhone XS Max 和 iPhone SE的PPI划分为458和326,这足以证明前者的屏幕更清晰。

由于手机尺寸为手机对角线的长度,我们通常使用如下的方法盘算PPI:iPhone 6的PPI为 ,那它每英寸约含有326个物理像素点。2.5 DPIDPI(Dot Per Inch):即每英寸包罗的点数。这里的点是一个抽象的单元,它可以是屏幕像素点、图片像素点也可以是打印机的墨点。

平时你可能会看到使用DPI来形貌图片和屏幕,这时的DPI应该和PPI是等价的,DPI最常用的是用于形貌打印机,表现打印机每英寸可以打印的点数。一张图片在屏幕上显示时,它的像素点数是规则排列的,每个像素点都有特定的位置和颜色。当使用打印机举行打印时,打印机可能不会规则的将这些点打印出来,而是使用一个个打印点来出现这张图像,这些打印点之间会有一定的清闲,这就是DPI所形貌的:打印点的密度。在上面的图像中我们可以清晰的看到,打印机是如何使用墨点来打印一张图像。

所以,打印机的DPI越高,打印图像的精致水平就越高,同时这也会消耗更多的墨点和时间。三、设备独立像素实际上,上面我们形貌的像素都是物理像素,即设备上真实的物理单元。下面我们来看看设备独立像素究竟是如何发生的:智能手机生长很是之快,在几年之前,我们还用着分辨率很是低的手机,好比下面左侧的白色手机,它的分辨率是320x480,我们可以在上面浏览正常的文字、图片等等。可是,随着科技的生长,低分辨率的手机已经不能满足我们的需求了。

很快,更高分辨率的屏幕降生了,好比下面的玄色手机,它的分辨率是640x940,正好是白色手机的两倍。理论上来讲,在白色手机上相同巨细的图片和文字,在玄色手机上会被缩放一倍,因为它的分辨率提高了一倍。这样,岂不是后面泛起更高分辨率的手机,页面元素会变得越来越小吗?然而,事实并不是这样的,我们现在使用的智能手机,不管分辨率多高,他们所展示的界面比例都是基本类似的。乔布斯在iPhone4的公布会上首次提出了Retina Display(视网膜屏幕)的观点,它正是解决了上面的问题,这也使它成为一款跨时代的手机。

在iPhone4使用的视网膜屏幕中,把2x2个像素当1个像素使用,这样让屏幕看起来更精致,可是元素的巨细却不会改变。如果玄色手机使用了视网膜屏幕的技术,那么显示效果应该是下面的情况,好比列表的宽度为300个像素,那么在一条水平线上,白色手时机用300个物理像素去渲染它,而玄色手机实际上会用600个物理像素去渲染它。我们必须用一种单元来同时告诉差别分辨率的手机,它们在界面上显示元素的巨细是几多,这个单元就是设备独立像素(Device Independent Pixels)简称DIP或DP。上面我们说,列表的宽度为300个像素,实际上我们可以说:列表的宽度为300个设备独立像素。

打开chrome的开发者工具,我们可以模拟各个手机型号的显示情况,每种型号上面会显示一个尺寸,好比iPhone X显示的尺寸是375x812,实际iPhone X的分辨率会比这高许多,这里显示的就是设备独立像素。3.1 设备像素比设备像素比device pixel ratio简称dpr,即物理像素和设备独立像素的比值。

在web中,浏览器为我们提供了window.devicePixelRatio来资助我们获取dpr。在css中,可以使用媒体查询min-device-pixel-ratio,区分dpr:@media (-webkit-min-device-pixel-ratio: 2),(min-device-pixel-ratio: 2){ }在React Native中,我们也可以使用PixelRatio.get()来获取DPR。固然,上面的规则也有破例,iPhone 6、7、8 Plus的实际物理像素是1080 x 1920,在开发者工具中我们可以看到:它的设备独立像素是414 x 736,设备像素比为3,设备独立像素和设备像素比的乘积并不即是1080 x 1920,而是即是1242 x 2208。

实际上,手时机自动把1242 x 2208个像素点塞进1080 * 1920个物理像素点来渲染,我们不用体贴这个历程,而1242 x 2208被称为屏幕的设计像素。我们开发历程中也是以这个设计像素为准。

实际上,从苹果提出视网膜屏幕开始,才泛起设备像素比这个观点,因为在这之前,移动设备都是直接使用物理像素来举行展示。紧接着,Android同样使用了其他的技术方案来实现DPR大于1的屏幕,不外原理是类似的。由于Android屏幕尺寸很是多、分辨率崎岖跨度很是大,不像苹果只有它自己的几款牢固设备、尺寸。所以,为了保证种种设备的显示效果,Android根据设备的像素密度将设备分成了几个区间:固然,所有的Android设备纷歧定严格根据上面的分辨率,每个类型可能对应几种差别分辨率,所以,每个Android手机都能凭据给定的区间规模,确定自己的DPR,从而拥有类似的显示。

固然,仅仅是类似,由于各个设备的尺寸、分辨率上的差异,设备独立像素也不会完全相等,所以种种Android设备仍然不能做到在展示上完全相等。3.2 移动端开发在iOS、Android和React Native开发中样式单元其实都使用的是设备独立像素。iOS的尺寸单元为pt,Android的尺寸单元为dp,React Native中没有指定明确的单元,它们其实都是设备独立像素dp。在使用React Native开发App时,UI给我们的原型图一般是基于iphone6的像素给定的。

为了适配所有机型,我们在写样式时需要把物理像素转换为设备独立像素:例如:如果给定一个元素的高度为200px(这里的px指物理像素,非CSS像素),iphone6的设备像素比为2,我们给定的height应为200px/2=100dp。固然,最好的是,你可以和设计相同好,所有的UI图都根据设备独立像素来出。我们还可以在代码(React Native)中举行px和dp的转换:import {PixelRatio } from 'react-native';const dpr = PixelRatio.get();/** * px转换为dp */export function pxConvertTodp(px) { return px / dpr;}/** * dp转换为px */export function dpConvertTopx(dp) { return PixelRatio.getPixelSizeForLayoutSize(dp);}3.3 WEB端开发在写CSS时,我们用到最多的单元是px,即CSS像素,当页面缩放比例为100%时,一个CSS像素即是一个设备独立像素。可是CSS像素是很容易被改变的,当用户对浏览器举行了放大,CSS像素会被放大,这时一个CSS像素会跨越更多的物理像素。

页面的缩放系数 = CSS像素 / 设备独立像素。3.4 关于屏幕这里多说两句Retina屏幕,因为我在许多文章中看到对Retina屏幕的误解。Retina屏幕只是苹果提出的一个营销术语:在普通的使用距离下,人的肉眼无法分辨单个的像素点。

为什么强调普通的使用距离下呢?我们来看一下它的盘算公式:a代表人眼视角,h代表像素间距,d代表肉眼与屏幕的距离,切合以上条件的屏幕可以使肉眼看不见单个物理像素点。它不能单纯的表达分辨率和PPI,只能一种表达视觉效果。让多个物理像素渲染一个独立像素只是Retina屏幕为了到达效果而使用的一种技术。

而不是所有DPR > 1的屏幕就是Retina屏幕。好比:给你一块超大尺寸的屏幕,纵然它的PPI很高,DPR也很高,在近距离你也能看清它的像素点,这就不算Retina屏幕。我们经常见到用K和P这个单元来形容屏幕:P代表的就是屏幕纵向的像素个数,1080P即纵向有1080个像素,分辨率为1920X1080的屏幕就属于1080P屏幕。

我们平时所说的高清屏其实就是屏幕的物理分辨率到达或凌驾1920X1080的屏幕。K代表屏幕横向有几个1024个像素,一般来讲横向像素凌驾2048就属于2K屏,横向像素凌驾4096就属于4K屏。四、视口视口(viewport)代表当前可见的盘算机图形区域。

开云体育官网

在Web浏览器术语中,通常与浏览器窗口相同,但不包罗浏览器的UI, 菜单栏等——即指你正在浏览的文档的那一部门。一般我们所说的视口共包罗三种:结构视口、视觉视口和理想视口,它们在屏幕适配中起着很是重要的作用。4.1 结构视口结构视口(layout viewport):当我们以百分比来指定一个元素的巨细时,它的盘算值是由这个元素的包罗块盘算而来的。当这个元素是最顶级的元素时,它就是基于结构视口来盘算的。

所以,结构视口是网页结构的基准窗口,在PC浏览器上,结构视口就即是当前浏览器的窗口巨细(不包罗borders 、margins、转动条)。在移动端,结构视口被赋予一个默认值,大部门为980px,这保证PC的网页可以在手机浏览器上出现,可是很是小,用户可以手动对网页举行放大。

我们可以通过挪用document.documentElement.clientWidth / clientHeight来获取结构视口巨细。4.2 视觉视口视觉视口(visual viewport):用户通过屏幕真实看到的区域。视觉视口默认即是当前浏览器的窗口巨细(包罗转动条宽度)。当用户对浏览器举行缩放时,不会改变结构视口的巨细,所以页面结构是稳定的,可是缩放会改变视觉视口的巨细。

例如:用户将浏览器窗口放大了200%,这时浏览器窗口中的CSS像素会随着视觉视口的放大而放大,这时一个CSS像素会跨越更多的物理像素。所以,结构视口会限制你的CSS结构而视觉视口决议用户详细能看到什么。

我们可以通过挪用window.innerWidth / innerHeight来获取视觉视口巨细。4.3 理想视口结构视口在移动端展示的效果并不是一个理想的效果,所以理想视口(ideal viewport)就降生了:网站页面在移动端展示的理想巨细。如上图,我们在形貌设备独立像素时曾使用过这张图,在浏览器调试移动端时页面上给定的像素巨细就是理想视口巨细,它的单元正是设备独立像素。

上面在先容CSS像素时曾经提到页面的缩放系数 = CSS像素 / 设备独立像素,实际上说页面的缩放系数 = 理想视口宽度 / 视觉视口宽度更为准确。所以,当页面缩放比例为100%时,CSS像素 = 设备独立像素,理想视口 = 视觉视口。我们可以通过挪用screen.width / height来获取理想视口巨细。4.4 Meta viewport<meta> 元素表现那些不能由其它HTML元相关元素之一表现的任何元数据信息,它可以告诉浏览器如何剖析页面。

我们可以借助<meta>元素的viewport来资助我们设置视口、缩放等,从而让移动端获得更好的展示效果。<meta name="viewport" content="width=device-width; initial-scale=1; maximum-scale=1; minimum-scale=1; user-scalable=no;">上面是viewport的一个设置,我们来看看它们的详细寄义: Value 可能值 形貌 width 正整数或device-width 以pixels(像素)为单元, 界说结构视口的宽度。height 正整数或device-height 以pixels(像素)为单元, 界说结构视口的高度。

initial-scale 0.0 - 10.0 界说页面初始缩放比率。minimum-scale 0.0 - 10.0 界说缩放的最小值;必须小于或即是maximum-scale的值。maximum-scale 0.0 - 10.0 界说缩放的最大值;必须大于或即是minimum-scale的值。user-scalable 一个布尔值(yes或者no) 如果设置为 no,用户将不能放大或缩小网页。

默认值为 yes。4.5 移动端适配为了在移动端让页面获得更好的显示效果,我们必须让结构视口、视觉视口都尽可能即是理想视口。

device-width就即是理想视口的宽度,所以设置width=device-width就相当于让结构视口即是理想视口。由于initial-scale = 理想视口宽度 / 视觉视口宽度,所以我们设置initial-scale=1;就相当于让视觉视口即是理想视口。

这时,1个CSS像素就即是1个设备独立像素,而且我们也是基于理想视口来举行结构的,所以出现出来的页面结构在种种设备上都能大致相似。4.6 缩放上面提到width可以决议结构视口的宽度,实际上它并不是结构视口的唯一决议性因素,设置initial-scale也有肯能影响到结构视口,因为结构视口宽度取的是width和视觉视口宽度的最大值。例如:若手机的理想视口宽度为400px,设置width=device-width,initial-scale=2,此时视觉视口宽度 = 理想视口宽度 / initial-scale即200px,结构视口取两者最大值即device-width 400px。

若设置width=device-width,initial-scale=0.5,此时视觉视口宽度 = 理想视口宽度 / initial-scale即800px,结构视口取两者最大值即800px。4.7 获取浏览器巨细浏览器为我们提供的获取窗口巨细的API有许多,下面我们再来对比一下:window.innerHeight:获取浏览器视觉视口高度(包罗垂直转动条)。

window.outerHeight:获取浏览器窗口外部的高度。表现整个浏览器窗口的高度,包罗侧边栏、窗口镶边和调正窗口巨细的边框。window.screen.Height:获取获屏幕取理想视口高度,这个数值是牢固的,设备的分辨率/设备像素比window.screen.availHeight:浏览器窗口可用的高度。

开云体育官网

document.documentElement.clientHeight:获取浏览器结构视口高度,包罗内边距,但不包罗垂直转动条、边框和外边距。document.documentElement.offsetHeight:包罗内边距、转动条、边框和外边距。document.documentElement.scrollHeight:在不使用转动条的情况下适合视口中的所有内容所需的最小宽度。

丈量方式与clientHeight相同:它包罗元素的内边距,但不包罗边框,外边距或垂直转动条。五、1px问题为了适配种种屏幕,我们写代码时一般使用设备独立像素来对页面举行结构。

而在设备像素比大于1的屏幕上,我们写的1px实际上是被多个物理像素渲染,这就会泛起1px在有些屏幕上看起来很粗的现象。5.1 border-image基于media查询判断差别的设备像素比给定差别的border-image: .border_1px{ border-bottom: 1px solid #000; } @media only screen and (-webkit-min-device-pixel-ratio:2){ .border_1px{ border-bottom: none; border-width: 0 0 1px 0; border-image: url(../img/1pxline.png) 0 0 2 0 stretch; } }5.2 background-image和border-image类似,准备一张切合条件的边框配景图,模拟在配景上。.border_1px{ border-bottom: 1px solid #000; } @media only screen and (-webkit-min-device-pixel-ratio:2){ .border_1px{ background: url(../img/1pxline.png) repeat-x left bottom; background-size: 100% 1px; } }上面两种都需要单独准备图片,而且圆角不是很利益理,可是可以应对大部门场景。

5.3 伪类 + transform基于media查询判断差别的设备像素比对线条举行缩放: .border_1px:before{ content: ''; position: absolute; top: 0; height: 1px; width: 100%; background-color: #000; transform-origin: 50% 0%; } @media only screen and (-webkit-min-device-pixel-ratio:2){ .border_1px:before{ transform: scaleY(0.5); } } @media only screen and (-webkit-min-device-pixel-ratio:3){ .border_1px:before{ transform: scaleY(0.33); } }这种方式可以满足种种场景,如果需要满足圆角,只需要给伪类也加上border-radius即可。5.4 svg上面我们border-image和background-image都可以模拟1px边框,可是使用的都是位图,还需要外部引入。借助PostCSS的postcss-write-svg我们能直接使用border-image和background-image建立svg的1px边框:@svg border_1px { height: 2px; @rect { fill: var(--color, black); width: 100%; height: 50%; } } .example { border: 1px solid transparent; border-image: svg(border_1px param(--color #00b1ff)) 2 2 stretch; }编译后:.example { border: 1px solid transparent; border-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' height='2px'%3E%3Crect fill='%2300b1ff' width='100%25' height='50%25'/%3E%3C/svg%3E") 2 2 stretch; }上面的方案是大漠在他的文章中推荐使用的,基本可以满足所有场景,而且不需要外部引入,这是我小我私家比力喜欢的一种方案。

5.5 设置viewport通过设置缩放,让CSS像素即是真正的物理像素。例如:当设备像素比为3时,我们将页面缩放1/3倍,这时1px即是一个真正的屏幕像素。const scale = 1 / window.devicePixelRatio; const viewport = document.querySelector('meta[name="viewport"]'); if (!viewport) { viewport = document.createElement('meta'); viewport.setAttribute('name', 'viewport'); window.document.head.appendChild(viewport); } viewport.setAttribute('content', 'width=device-width,user-scalable=no,initial-scale=' + scale + ',maximum-scale=' + scale + ',minimum-scale=' + scale);实际上,上面这种方案是早先flexible接纳的方案。固然,这样做是要支付价格的,这意味着你页面上所有的结构都要根据物理像素来写。

这显然是不现实的,这时,我们可以借助flexible或vw、vh来资助我们举行适配。六、移动端适配方案只管我们可以使用设备独立像素来保证各个设备在差别手机上显示的效果类似,但这并不能保证它们显示完全一致,我们需要一种方案来让设计稿获得更完美的适配。

6.1 flexible方案flexible方案是阿里早期开源的一个移动端适配解决方案,引用flexible后,我们在页面上统一使用rem来结构。它的焦点代码很是简朴:// set 1rem = viewWidth / 10function setRemUnit () { var rem = docEl.clientWidth / 10 docEl.style.fontSize = rem + 'px'}setRemUnit();rem 是相对于html节点的font-size来做盘算的。我们通过设置document.documentElement.style.fontSize就可以统一整个页面的结构尺度。上面的代码中,将html节点的font-size设置为页面clientWidth(结构视口)的1/10,即1rem就即是页面结构视口的1/10,这就意味着我们后面使用的rem都是根据页面比例来盘算的。

这时,我们只需要将UI出的图转换为rem即可。以iPhone6为例:结构视口为375px,则1rem = 37.5px,这时UI给定一个元素的宽为75px(设备独立像素),我们只需要将它设置为75 / 37.5 = 2rem。固然,每个结构都要盘算很是繁琐,我们可以借助PostCSS的px2rem插件来资助我们完成这个历程。下面的代码可以保证在页面巨细变化时,结构可以自适应,当触发了window的resize和pageShow事件之后自动调整html的fontSize巨细。

// reset rem unit on page resizewindow.addEventListener('resize', setRemUnit)window.addEventListener('pageshow', function (e) { if (e.persisted) { setRemUnit() }})由于viewport单元获得众多浏览器的兼容,上面这种方案现在已经被官方弃用:lib-flexible这个过渡方案已经可以放弃使用,不管是现在的版本还是以前的版本,都存有一定的问题。建议大家开始使用viewport来替代此方案。下面我们来看看现在最盛行的vh、vw方案。6.2 vh、vw方案vh、vw方案即将视觉视口宽度 window.innerWidth和视觉视口高度 window.innerHeight 平分为 100 份。

上面的flexible方案就是模拟这种方案,因为早些时候vw还没有获得很好的兼容。vw(Viewport's width):1vw即是视觉视口的1%vh(Viewport's height) :1vh 为视觉视口高度的1%vmin : vw 和 vh 中的较小值vmax : 选取 vw 和 vh 中的较大值如果视觉视口为375px,那么1vw = 3.75px,这时UI给定一个元素的宽为75px(设备独立像素),我们只需要将它设置为75 / 3.75 = 20vw。

这里的比例关系我们也不用自己换算,我们可以使用PostCSS的 postcss-px-to-viewport 插件帮我们完成这个历程。写代码时,我们只需要凭据UI给的设计图写px单元即可。固然,没有一种方案是十全十美的,vw同样有一定的缺陷:px转换成vw纷歧定能完全整除,因此有一定的像素差。

好比当容器使用vw,margin接纳px时,很容易造成整体宽度凌驾100vw,从而影响结构效果。固然我们也是可以制止的,例如使用padding取代margin,联合calc()函数使用等等...七、适配iPhoneXiPhoneX的泛起将手机的颜值带上了一个新的高度,它取消了物理按键,改成了底部的小黑条,可是这样的改动给开发者适配移动端又增加了难度。7.1 宁静区域在iPhoneX公布后,许多厂商相继推出了具有边缘屏幕的手机。这些手机和普通手机在外观上无外乎做了三个改动:圆角(corners)、刘海(sensor housing)和小黑条(Home Indicator)。

为了适配这些手机,宁静区域这个观点变降生了:宁静区域就是一个不受上面三个效果的可视窗口规模。为了保证页面的显示效果,我们必须把页面限制在宁静规模内,可是不影响整体效果。7.2 viewport-fitviewport-fit是专门为了适配iPhoneX而降生的一个属性,它用于限制网页如何在宁静区域内举行展示。contain: 可视窗口完全包罗网页内容cover:网页内容完全笼罩可视窗口默认情况下或者设置为auto和contain效果相同。

7.3 env、constant我们需要将顶部和底部合理的摆放在宁静区域内,iOS11新增了两个CSS函数env、constant,用于设定宁静区域与界限的距离。函数内部可以是四个常量:safe-area-inset-left:宁静区域距离左边界限距离safe-area-inset-right:宁静区域距离右边界限距离safe-area-inset-top:宁静区域距离顶部界限距离safe-area-inset-bottom:宁静区域距离底部界限距离注意:我们必须指定viweport-fit后才气使用这两个函数:<meta name="viewport" content="viewport-fit=cover">constant在iOS < 11.2的版本中生效,env在iOS >= 11.2的版本中生效,这意味着我们往往要同时设置他们,将页面限制在宁静区域内:body { padding-bottom: constant(safe-area-inset-bottom); padding-bottom: env(safe-area-inset-bottom);}当使用底部牢固导航栏时,我们要为他们设置padding值:{ padding-bottom: constant(safe-area-inset-bottom); padding-bottom: env(safe-area-inset-bottom);}八、横屏适配许多视口我们要对横屏和竖屏显示差别的结构,所以我们需要检测在差别的场景下给定差别的样式:8.1 JavaScript检测横屏window.orientation:获取屏幕旋转偏向window.addEventListener("resize", ()=>{ if (window.orientation === 180 || window.orientation === 0) { // 正常偏向或屏幕旋转180度 console.log('竖屏'); }; if (window.orientation === 90 || window.orientation === -90 ){ // 屏幕顺时钟旋转90度或屏幕逆时针旋转90度 console.log('横屏'); } }); 8.2 CSS检测横屏@media screen and (orientation: portrait) { /*竖屏...*/} @media screen and (orientation: landscape) { /*横屏...*/}九、图片模糊问题9.1 发生原因我们平时使用的图片大多数都属于位图(png、jpg...),位图由一个个像素点组成的,每个像素都具有特定的位置和颜色值:理论上,位图的每个像素对应在屏幕上使用一个物理像素来渲染,才气到达最佳的显示效果。而在dpr > 1的屏幕上,位图的一个像素可能由多个物理像素来渲染,然而这些物理像素点并不能被准确的分配上对应位图像素的颜色,只能取近似值,所以相同的图片在dpr > 1的屏幕上就会模糊:9.2 解决方案为了保证图片质量,我们应该尽可能让一个屏幕像素来渲染一个图片像素,所以,针对差别DPR的屏幕,我们需要展示差别分辨率的图片。

如:在dpr=2的屏幕上展示两倍图(@2x),在dpr=3的屏幕上展示三倍图(@3x)。9.3 media查询使用media查询判断差别的设备像素比来显示差别精度的图片: .avatar{ background-image: url(conardLi_1x.png); } @media only screen and (-webkit-min-device-pixel-ratio:2){ .avatar{ background-image: url(conardLi_2x.png); } } @media only screen and (-webkit-min-device-pixel-ratio:3){ .avatar{ background-image: url(conardLi_3x.png); } }只适用于配景图9.4 image-set使用image-set:.avatar { background-image: -webkit-image-set( "conardLi_1x.png" 1x, "conardLi_2x.png" 2x );}只适用于配景图9.5 srcset使用img标签的srcset属性,浏览器会自动凭据像素密度匹配最佳显示图片:<img src="conardLi_1x.png" srcset=" conardLi_2x.png 2x, conardLi_3x.png 3x">9.6 JavaScript拼接图片url使用window.devicePixelRatio获取设备像素比,遍历所有图片,替换图片地址:const dpr = window.devicePixelRatio;const images = document.querySelectorAll('img');images.forEach((img)=>{ img.src.replace(".", `@${dpr}x.`);})9.7 使用svgSVG的全称是可缩放矢量图(Scalable Vector Graphics)。差别于位图的基于像素,SVG 则是属于对图像的形状形貌,所以它本质上是文本文件,体积较小,且不管放大几多倍都不会失真。除了我们手动在代码中绘制svg,我们还可以像使用位图一样使用svg图片:<img src="conardLi.svg"><img src="data:image/svg+xml;base64,[data]">.avatar { background: url(conardLi.svg);}作者:ConardLi链接:https://juejin.im/post/5cddf289f265da038f77696c泉源:掘金。


本文关键词:开云体育官网
中国有限公司