自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

一篇搞定移動(dòng)端適配

移動(dòng)開發(fā) Android
手機(jī)市場日漸豐富的同時(shí),給我們前端開發(fā)人員帶來的 “網(wǎng)頁內(nèi)容自適應(yīng)屏幕尺寸進(jìn)行顯示的問題” 也日漸凸顯出來,接下來我們就要細(xì)說移動(dòng)端適配的前世今生及方案。

 [[319272]]

前言

手機(jī)市場日漸豐富的同時(shí),給我們前端開發(fā)人員帶來的 “網(wǎng)頁內(nèi)容自適應(yīng)屏幕尺寸進(jìn)行顯示的問題” 也日漸凸顯出來,接下來我們就要細(xì)說移動(dòng)端適配的前世今生及方案。

一、為什么要移動(dòng)端適配?

一般情況下設(shè)計(jì)稿的設(shè)計(jì)師按照 375 的尺寸設(shè)計(jì),然而,在現(xiàn)在移動(dòng)終端(就是手機(jī))快速更新的時(shí)代,每個(gè)品牌的手機(jī)都有著不同的物理分辨率,這樣就會(huì)導(dǎo)致,每臺設(shè)備的邏輯分辨率也不盡相同,此時(shí) 375 的設(shè)計(jì)稿,如果想要還原那基本是不可能了,因?yàn)槿绻粋€(gè)左右布局,左邊如果寫死,右邊自適應(yīng)的話,每個(gè)設(shè)備的右邊所展示的內(nèi)容大小就不盡相同,這時(shí)移動(dòng)端適配就顯得尤其重要。

既然要了解前世今生,我們就從幾個(gè)概念說起,先上一張圖。

 

 

 

 

下面我們一個(gè)個(gè)解析

1.1 屏幕尺寸

屏幕尺寸是以屏幕對角線的長度來計(jì)量,計(jì)量單位為英寸。

如圖所示兩個(gè)對角線的長度就是這個(gè)屏幕的尺寸

 

 

 

[[319273]]

 

1.2 像素

我們看到上圖 320x480 叫分辨率,而這個(gè)所謂的分辨率說白了就是橫向320個(gè)像素縱向480個(gè)像素組成

1.2.1 什么叫像素呢?

像素(Pel, pixel, pictureelement),為組成一幅圖像的全部亮度和色度的最小圖像單元。電視的圖像是由按一定間隔排列的亮度不同的像點(diǎn)構(gòu)成的,形成像點(diǎn)的單位也就是像素,組成圖像的最小單位就是像素。從計(jì)算機(jī)技術(shù)的角度來解釋,像素是硬件和軟件所能控制的最小單位。它指顯示屏的畫面上表示出來的最小單位,不是圖畫上的最小單位。一幅圖像通常包含成千上萬個(gè)像素,每個(gè)像素都有自己的顏色信息,它們緊密地組合在一起。由于人眼的錯(cuò)覺,這些組合在一起的像素被當(dāng)成一幅完整的圖像。當(dāng)修改圖像的某區(qū)域,實(shí)際上是在修改該區(qū)域內(nèi)的像素。對這些像素修改的好與壞將決定最終圖片的質(zhì)量。單位面積內(nèi)的像素越多,圖像的效果就越好。彩色電視圖像是由成千個(gè)像素點(diǎn)所組成的,而且每個(gè)像素都是由紅綠藍(lán)三種顏色并排組成的。(注意每個(gè)像素的大小是不固定的,他是根據(jù)設(shè)備的分辨率決定的,知識點(diǎn),后面要考)

1.2.2 什么叫分辨率呢?

屏幕分辨率是指縱橫向上的像素點(diǎn)數(shù),單位是 px。屏幕分辨率確定計(jì)算機(jī)屏幕上顯示多少信息的設(shè)置,以水平和垂直像素來衡量。就相同大小的屏幕而言,當(dāng)屏幕分辨率低時(shí)(例如 640 x 480),在屏幕上顯示的像素少,單個(gè)像素尺寸比較大。屏幕分辨率高時(shí)(例如 1600 x 1200),在屏幕上顯示的像素多,單個(gè)像素尺寸比較小。

知道什么叫做分辨率后,有人就會(huì)奇怪,我記得蘋果的蘋果官網(wǎng)上的蘋果 6 的分辨率為 750x1334 啊,但是設(shè)計(jì)稿上蘋果 6 的分辨率為 375x667 啊,而且各個(gè)設(shè)備的分辨率都比實(shí)際分辨率小很多,這就牽扯到一些歷史原因了

1.2.3 設(shè)備物理分辨率(設(shè)備像素)

相信我們所有前端開發(fā)者,都是見證了手機(jī)這個(gè)移動(dòng)設(shè)備發(fā)展的過程。從藍(lán)屏手機(jī),到彩屏手機(jī),到諾基亞研發(fā)出來觸屏手機(jī),再到智能手機(jī)一步步發(fā)展下來,我們的我們的手越來越清晰,越來越大,所以我們的屏幕發(fā)展也越來越迅速。

 

 

 

[[319274]]

 

上圖可以清楚的看到,不同分辨率所帶來的的差距

從最初的顆粒感相當(dāng)大的屏幕,到 720p 再到 1080p,甚至于現(xiàn)在各家旗艦手機(jī)的 2k 屏幕,我們的物理分辨率在變得原來越大。這樣就暴露出來一個(gè)問題,我們?nèi)绻謾C(jī)分辨率翻倍,我們的圖像不就要被縮小一倍,我們難道要在每個(gè)設(shè)備上就出個(gè)設(shè)計(jì)稿,每個(gè)設(shè)備的分辨不盡相同啊,其實(shí)你擔(dān)憂的問題,我們的喬幫主在很多年前就想到了。這就是我們的邏輯分辨率

1.2.4 邏輯分辨率(設(shè)備獨(dú)立像素)

如下圖所示,雖然設(shè)備物理分辨不同,但是他的這個(gè)邏輯分辨率卻都差不多,這就要感謝喬幫主了。

 

 

 

 

喬布斯在 iPhone4 的發(fā)布會(huì)上首次提出了 Retina Display(視網(wǎng)膜屏幕)的概念,在 iPhone4 使用的視網(wǎng)膜屏幕中,把 2x2 個(gè)像素當(dāng) 1 個(gè)像素使用,這樣讓屏幕看起來更精致,但是元素的大小卻不會(huì)改變。從此以后高分辨率的設(shè)備,多了一個(gè)邏輯像素。這些設(shè)備邏輯像素的差別雖然不會(huì)跨度很大,但是仍然有點(diǎn)差別,于是便誕生了移動(dòng)端頁面需要適配這個(gè)問題,既然邏輯像素由物理像素得來,那他們就會(huì)有一個(gè)像素比值。

1.2.5 設(shè)備像素比

設(shè)備像素比 device pixel ratio 簡稱 dpr,即物理像素和設(shè)備獨(dú)立像素的比值。為什么要知道設(shè)備像素比呢?因?yàn)檫@個(gè)像素比會(huì)產(chǎn)生一個(gè)非常經(jīng)典的問題,1 像素邊框的問題。

1px 邊框問題

當(dāng)我們 css 里寫的 1px 的時(shí)候,由于它是邏輯像素,導(dǎo)致我們的邏輯像素根據(jù)這個(gè)設(shè)備像素比(dpr)去映射到設(shè)備上就為 2px,或者 3px,由于每個(gè)設(shè)備的屏幕尺寸不一樣,就導(dǎo)致每個(gè)物理像素渲染出來的大小也不同(記得上面的知識點(diǎn)嗎,設(shè)備的像素大小是不固定的),這樣如果在尺寸比較大的設(shè)備上,1px 渲染出來的樣子相當(dāng)?shù)拇值V,這就是經(jīng)典的一像素邊框問題。

如何解決

核心思路,就是在 web 中,瀏覽器為我們提供了 window.devicePixelRatio 來幫助我們獲取 dpr。在 css 中,可以使用媒體查詢 min-device-pixel-ratio,區(qū)分 dpr:我們根據(jù)這個(gè)像素比,來算出他對應(yīng)應(yīng)該有的大小,但是暴露個(gè)非常大的兼容問題。

 

 

 

[[319275]]

 

其中 Chrome 把 0.5px 四舍五入變成了 1px,而 firefox/safari 能夠畫出半個(gè)像素的邊,并且 Chrome 會(huì)把小于 0.5px 的當(dāng)成 0,而 Firefox 會(huì)把不小于 0.55px 當(dāng)成 1px,Safari 是把不小于 0.75px 當(dāng)成 1px,進(jìn)一步在手機(jī)上觀察 iOS 的 Chrome 會(huì)畫出 0.5px 的邊,而安卓(5.0)原生瀏覽器是不行的。所以直接設(shè)置 0.5px 不同瀏覽器的差異比較大,并且我們看到不同系統(tǒng)的不同瀏覽器對小數(shù)點(diǎn)的 px 有不同的處理。所以如果我們把單位設(shè)置成小數(shù)的 px 包括寬高等,其實(shí)不太可靠,因?yàn)椴煌瑸g覽器表現(xiàn)不一樣。

至于其他解決一像素邊框問題網(wǎng)上有一堆答案,在這里我推薦一種非常好用,并且沒有副作用的解決方案。

transform: scale(0.5) 方案

 

  1. div { 
  2.     height:1px; 
  3.     background:#000; 
  4.     -webkit-transform: scaleY(0.5); 
  5.     -webkit-transform-origin:0 0; 
  6.     overflow: hidden; 

css 根據(jù)設(shè)備像素比媒體查詢后的解決方案

 

  1. /* 2倍屏 */ 
  2. @media only screen and (-webkit-min-device-pixel-ratio: 2.0) { 
  3.     .border-bottom::after { 
  4.         -webkit-transform: scaleY(0.5); 
  5.         transform: scaleY(0.5); 
  6.     } 
  7. /* 3倍屏 */ 
  8. @media only screen and (-webkit-min-device-pixel-ratio: 3.0) { 
  9.     .border-bottom::after { 
  10.         -webkit-transform: scaleY(0.33); 
  11.         transform: scaleY(0.33); 
  12.     } 

如此,完美的解決一像素看著粗的問題。

擴(kuò)展補(bǔ)充

CSS 最新的規(guī)范中正在計(jì)劃通過標(biāo)準(zhǔn)的屬性實(shí)現(xiàn)一像素邊框,通過給border-width屬性添加hairline關(guān)鍵字屬性來實(shí)現(xiàn),具體如下鏈接[1]。之所以叫hairline,是因?yàn)橐幌袼剡吙蚓透^發(fā)絲一樣。

練習(xí)使用方案時(shí),也要多多關(guān)注最新發(fā)展喲。

二、如何適配

2.1 viewport

視口(viewport)代表當(dāng)前可見的計(jì)算機(jī)圖形區(qū)域。在 Web 瀏覽器術(shù)語中,通常與瀏覽器窗口相同,但不包括瀏覽器的 UI, 菜單欄等——即指你正在瀏覽的文檔的那一部分。

那么在移動(dòng)端如何配置視口呢?簡單的一個(gè) meta 標(biāo)簽即可!

  1. <meta name="viewport" content="width=device-width; initial-scale=1; maximum-scale=1; minimum-scale=1; user-scalable=no;"

 

他們分別什么含義呢?

 

 

 

 

我們在移動(dòng)端視口要想視覺效果和體驗(yàn)好,那么我們的視口寬度必須無限接近理想視口。

理想視口:一般來講,這個(gè)視口其實(shí)不是真是存在的,它對設(shè)備來說是一個(gè)最理想布局視口尺寸,在用戶不進(jìn)行手動(dòng)縮放的情況下,可以將頁面理想地展示。那么所謂的理想寬度就是瀏覽器(屏幕)的寬度了。

于是上述的 meta 設(shè)置,就是我們的理想設(shè)置,他規(guī)定了我們的視口寬度為屏幕寬度,初始縮放比例為 1,就是初始時(shí)候我們的視覺視口就是理想視口!

其中 user-scalable 設(shè)置為 no 可以解決移動(dòng)端點(diǎn)擊事件延遲問題(拓展)

2.2 適配方法

2.2.1 rem 適配

rem 是 CSS3 新增的一個(gè)相對單位,這個(gè)單位引起了廣泛關(guān)注。這個(gè)單位與 em 有什么區(qū)別呢?區(qū)別在于使用 rem 為元素設(shè)定字體大小時(shí),仍然是相對大小,但相對的只是 HTML 根元素。這個(gè)單位可謂集相對大小和絕對大小的優(yōu)點(diǎn)于一身,通過它既可以做到只修改根元素就成比例地調(diào)整所有字體大小,又可以避免字體大小逐層復(fù)合的連鎖反應(yīng)。目前,除了 IE8 及更早版本外,所有瀏覽器均已支持 rem。對于不支持它的瀏覽器,應(yīng)對方法也很簡單,就是多寫一個(gè)絕對單位的聲明。這些瀏覽器會(huì)忽略用 rem 設(shè)定的字體大小。

舉個(gè)例子:

 

  1. //假設(shè)我給根元素的大小設(shè)置為14px 
  2. html{ 
  3.     font-size:14px 
  4. //那么我底下的p標(biāo)簽如果想要也是14像素 
  5. p{ 
  6.     font-size:1rem 
  7. //如此即可 

rem 的布局,不得不提 flexible,flexible 方案是阿里早期開源的一個(gè)移動(dòng)端適配解決方案,引用 flexible 后,我們在頁面上統(tǒng)一使用 rem 來布局。

他的原理非常簡單

 

  1. // set 1rem = viewWidth / 10 
  2. function setRemUnit () { 
  3.     var rem = docEl.clientWidth / 10 
  4.     docEl.style.fontSize = rem + 'px' 
  5. setRemUnit(); 

rem 是相對于 html 節(jié)點(diǎn)的 font-size 來做計(jì)算的。所以在頁面初始話的時(shí)候給根元素設(shè)置一個(gè) font-size,接下來的元素就根據(jù) rem 來布局,這樣就可以保證在頁面大小變化時(shí),布局可以自適應(yīng)。

如此我們只需要給設(shè)計(jì)稿的 px 轉(zhuǎn)換成對應(yīng)的 rem 單位即可。

當(dāng)然,這個(gè)方案只是個(gè)過渡方案,為什么說是過渡方案

因?yàn)楫?dāng)年 viewport 在低版本安卓設(shè)備上還有兼容問題,而 vw,vh 還沒能實(shí)現(xiàn)所有瀏覽器兼容,所以 flexible 方案用 rem 來模擬 vmin 來實(shí)現(xiàn)在不同設(shè)備等比縮放的“過度”方案,之所以說是過度方案,是因?yàn)檫@個(gè)他這個(gè)根據(jù)設(shè)備大小去判斷頁面的方案是根據(jù)屏幕大小去百分百還原設(shè)計(jì)稿,從而讓人看到的大小效果是一樣的,但是 蘋果 5 和蘋果 6p 雖然看到的設(shè)計(jì)稿還原是一樣的,但是他在一個(gè)合適距離上看到的效果能一樣嗎,本質(zhì)上,用戶使用更大的屏幕,是想看到更多的內(nèi)容,而不是更大的字。

so,這個(gè)用縮放來解決問題的方案是個(gè)過渡方案,注定被時(shí)代所淘汰。

2.2.2 vw,vh 布局

vh、vw 方案即將視覺視口寬度 window.innerWidth 和視覺視口高度 window.innerHeight 等分為 100 份。

 

 

 

[[319276]]

 

vh 和 vw 方案和 rem 類似也是相當(dāng)麻煩需要做單位轉(zhuǎn)化,而且 px 轉(zhuǎn)換成 vw 不一定能完全整除,因此有一定的像素差。

不過在工程化的今天,webpack 解析 css 的時(shí)候用 postcss-loader 有個(gè) postcss-px-to-viewport 能自動(dòng)實(shí)現(xiàn) px 到 vw 的轉(zhuǎn)化

 

  1.     loader: 'postcss-loader'
  2.     options: { 
  3.         plugins: ()=>[ 
  4.             require('autoprefixer')({ 
  5.                 browsers: ['last 5 versions'
  6.             }), 
  7.             require('postcss-px-to-viewport')({ 
  8.                 viewportWidth: 375, //視口寬度(數(shù)字) 
  9.                 viewportHeight: 1334, //視口高度(數(shù)字) 
  10.                 unitPrecision: 3, //設(shè)置的保留小數(shù)位數(shù)(數(shù)字) 
  11.                 viewportUnit: 'vw', //設(shè)置要轉(zhuǎn)換的單位(字符串) 
  12.                 selectorBlackList: ['.ignore''.hairlines'], //不需要進(jìn)行轉(zhuǎn)換的類名(數(shù)組) 
  13.                 minPixelValue: 1, //設(shè)置要替換的最小像素值(數(shù)字) 
  14.                 mediaQuery: false //允許在媒體查詢中轉(zhuǎn)換px(true/false) 
  15.             }) 
  16.         ] 

2.2.3 px 為主,vx 和 vxxx(vw/vh/vmax/vmin)為輔,搭配一些 flex(推薦)

之所以推薦使用此種方案,是由于我們要去考慮用戶的需求,用戶之所以去買大屏手機(jī),不是為了看到更大的字,而是為了看到更多的內(nèi)容,這樣直接使用 px 是最明智的方案,使用 vw,rem 等布局手段無可厚非,但是,flex 這種彈性布局大行其道的今天,如果如果還用這種傳統(tǒng)的思維去想問題顯然是有兩個(gè)原因(個(gè)人認(rèn)為 px 是最好的,可能有大佬,能用 vw,或者 rem 寫出精妙的布局,也說不準(zhǔn))。

  1. 為了偷懶,不愿意去做每個(gè)手機(jī)的適
  2. 不愿意去學(xué)習(xí)新的布局方式,讓 flex 等先進(jìn)的布局和你擦肩而過

2.3 移動(dòng)端適配流程

1. 在 head 設(shè)置 width=device-width 的 viewport‘

2. 在 css 中使用 px

3. 在適當(dāng)?shù)膱鼍笆褂?flex 布局,或者配合 vw 進(jìn)行自適應(yīng)

4. 在跨設(shè)備類型的時(shí)候(pc <-> 手機(jī) <-> 平板)使用媒體查詢

5. 在跨設(shè)備類型如果交互差異太大的情況,考慮分開項(xiàng)目開發(fā)

寫在最后

疫情期間有了跳槽的想法,問到移動(dòng)端布局方面,雖然勉強(qiáng)能回答上來,但是總是支支吾吾,不是很了解,故而,發(fā)下宏愿,梳理移動(dòng)端適配,幫助后來人后來者居上!

參考資料

[1]鏈接: https://github.com/w3c/csswg-drafts/issues/3720

責(zé)任編輯:武曉燕 來源: 歪碼行空
相關(guān)推薦

2020-08-11 09:06:42

監(jiān)控系統(tǒng)選型

2020-02-28 11:29:00

ElasticSear概念類比

2019-07-22 08:35:32

Java垃圾回收

2022-10-21 08:29:50

監(jiān)控CMDB架構(gòu)

2024-04-17 13:21:02

Python匿名函數(shù)

2021-05-15 10:16:14

Python匿名函數(shù)

2022-05-28 15:59:55

PythonPandas數(shù)據(jù)可視化

2018-12-18 11:20:28

前端模塊化JavaScript

2021-09-30 11:55:00

微服務(wù)

2021-03-06 10:05:03

Python函數(shù)變量

2023-01-06 18:50:55

架構(gòu)應(yīng)用

2021-11-10 09:19:41

PythonShutil模塊

2019-02-26 15:22:14

MySQL命令數(shù)據(jù)庫

2021-11-17 10:11:08

PythonLogging模塊

2022-03-30 10:51:40

JavaScript性能調(diào)優(yōu)

2020-03-31 08:37:31

遞歸單鏈表反轉(zhuǎn)

2022-05-12 10:36:10

移動(dòng)方案

2021-03-15 08:38:42

StringBuffeJava基礎(chǔ)Java開發(fā)

2021-02-20 10:06:14

語言文件操作

2021-02-27 10:20:18

Go語言flag包開發(fā)技術(shù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號