摘要:需要注意,上面的尺寸都是屏幕對角線的長度英寸縮寫為在荷蘭語中的本意是大拇指,一英寸就是指甲底部普通人拇指的寬度。由于手機(jī)尺寸為手機(jī)對角線的長度,我們通常使用如下的方法計(jì)算的為,那它每英寸約含有個(gè)物理像素點(diǎn)。
導(dǎo)讀
移動(dòng)端適配,是我們在開發(fā)中經(jīng)常會遇到的,這里面可能會遇到非常多的問題:
1px問題
UI圖完美適配方案
iPhoneX適配方案 橫屏適配 高清屏圖片模糊問題 ... 上面這些問題可能我們在開發(fā)中已經(jīng)知道如何解決,但是問題產(chǎn)生的原理,以及解決方案的原理可能會模糊不清。在解決這些問題的過程中,我們往往會遇到非常多的概念:像素、分辨率、
PPI、
DPI、
DP、
DIP、
DPR、視口等等,你真的能分清這些概念的意義嗎?
本文將從移動(dòng)端適配的基礎(chǔ)概念出發(fā),探究移動(dòng)端適配各種問題的解決方案和實(shí)現(xiàn)原理。
一、英寸
一般用英寸描述屏幕的物理大小,如電腦顯示器的
17、
22,手機(jī)顯示器的
4.8、
5.7等使用的單位都是英寸。
需要注意,上面的尺寸都是屏幕對角線的長度:?
?
英寸(inch,縮寫為
in)在荷蘭語中的本意是大拇指,一英寸就是指甲底部普通人拇指的寬度。
英寸和厘米的換算:1英寸 = 2.54 厘米
二、分辨率
2.1 像素
像素即一個(gè)小方塊,它具有特定的位置和顏色。
圖片、電子屏幕(手機(jī)、電腦)就是由無數(shù)個(gè)具有特定顏色和特定位置的小方塊拼接而成。
像素可以作為圖片或電子屏幕的最小組成單位。
下面我們使用
sketch打開一張圖片:
?
?
將這些圖片放大即可看到這些像素點(diǎn):
?
?
通常我們所說的分辨率有兩種,屏幕分辨率和圖像分辨率。
2.2 屏幕分辨率
屏幕分辨率指一個(gè)屏幕具體由多少個(gè)像素點(diǎn)組成。
下面是
apple的官網(wǎng)上對手機(jī)分辨率的描述:
?
?
iPhone XS Max 和iPhone SE的分辨率分別為
2688 x 1242和
1136 x 640。這表示手機(jī)分別在垂直和水平上所具有的像素點(diǎn)數(shù)。
當(dāng)然分辨率高不代表屏幕就清晰,屏幕的清晰程度還與尺寸有關(guān)。2.3 圖像分辨率
我們通常說的圖片分辨率其實(shí)是指圖片含有的
像素?cái)?shù),比如一張圖片的分辨率為
800 x 400。這表示圖片分別在垂直和水平上所具有的像素點(diǎn)數(shù)為
800和
400。
同一尺寸的圖片,分辨率越高,圖片越清晰。
?
?
2.4 PPI
PPI(Pixel Per Inch):每英寸包括的像素?cái)?shù)。 PPI可以用于描述屏幕的清晰度以及一張圖片的質(zhì)量。 使用
PPI描述圖片時(shí),
PPI越高,圖片質(zhì)量越高,使用
PPI描述屏幕時(shí),
PPI越高,屏幕越清晰。
在上面描述手機(jī)分辨率的圖片中,我們可以看到:
iPhone XS Max 和
iPhone SE的
PPI分別為
458和
326,這足以證明前者的屏幕更清晰。
由于手機(jī)尺寸為手機(jī)對角線的長度,我們通常使用如下的方法計(jì)算PPI:
iPhone 6的
PPI為 ,那它每英寸約含有
326個(gè)物理像素點(diǎn)。
2.5 DPI
DPI(Dot Per Inch):即每英寸包括的點(diǎn)數(shù)。 這里的點(diǎn)是一個(gè)抽象的單位,它可以是屏幕像素點(diǎn)、圖片像素點(diǎn)也可以是打印機(jī)的墨點(diǎn)。 平時(shí)你可能會看到使用
DPI來描述圖片和屏幕,這時(shí)的
DPI應(yīng)該和
PPI是等價(jià)的,
DPI最常用的是用于描述打印機(jī),表示打印機(jī)每英寸可以打印的點(diǎn)數(shù)。
一張圖片在屏幕上顯示時(shí),它的像素點(diǎn)數(shù)是規(guī)則排列的,每個(gè)像素點(diǎn)都有特定的位置和顏色。
當(dāng)使用打印機(jī)進(jìn)行打印時(shí),打印機(jī)可能不會規(guī)則的將這些點(diǎn)打印出來,而是使用一個(gè)個(gè)打印點(diǎn)來呈現(xiàn)這張圖像,這些打印點(diǎn)之間會有一定的空隙,這就是
DPI所描述的:打印點(diǎn)的密度。
?
?
在上面的圖像中我們可以清晰的看到,打印機(jī)是如何使用墨點(diǎn)來打印一張圖像。
所以,打印機(jī)的
DPI越高,打印圖像的精細(xì)程度就越高,同時(shí)這也會消耗更多的墨點(diǎn)和時(shí)間。
三、設(shè)備獨(dú)立像素
實(shí)際上,上面我們描述的像素都是
物理像素,即設(shè)備上真實(shí)的物理單元。
下面我們來看看設(shè)備獨(dú)立像素究竟是如何產(chǎn)生的:
智能手機(jī)發(fā)展非常之快,在幾年之前,我們還用著分辨率非常低的手機(jī),比如下面左側(cè)的白色手機(jī),它的分辨率是320x480,我們可以在上面瀏覽正常的文字、圖片等等。
但是,隨著科技的發(fā)展,低分辨率的手機(jī)已經(jīng)不能滿足我們的需求了。很快,更高分辨率的屏幕誕生了,比如下面的黑色手機(jī),它的分辨率是640x940,正好是白色手機(jī)的兩倍。
理論上來講,在白色手機(jī)上相同大小的圖片和文字,在黑色手機(jī)上會被縮放一倍,因?yàn)樗姆直媛侍岣吡艘槐丁_@樣,豈不是后面出現(xiàn)更高分辨率的手機(jī),頁面元素會變得越來越小嗎?
?
?
然而,事實(shí)并不是這樣的,我們現(xiàn)在使用的智能手機(jī),不管分辨率多高,他們所展示的界面比例都是基本類似的。喬布斯在
iPhone4的發(fā)布會上首次提出了
Retina Display(視網(wǎng)膜屏幕)的概念,它正是解決了上面的問題,這也使它成為一款跨時(shí)代的手機(jī)。
?
?
在
iPhone4使用的視網(wǎng)膜屏幕中,把
2x2個(gè)像素當(dāng)
1個(gè)像素使用,這樣讓屏幕看起來更精致,但是元素的大小卻不會改變。
?
?
如果黑色手機(jī)使用了視網(wǎng)膜屏幕的技術(shù),那么顯示結(jié)果應(yīng)該是下面的情況,比如列表的寬度為300個(gè)像素,那么在一條水平線上,白色手機(jī)會用
300個(gè)物理像素去渲染它,而黑色手機(jī)實(shí)際上會用
600個(gè)物理像素去渲染它。
我們必須用一種單位來同時(shí)告訴不同分辨率的手機(jī),它們在界面上顯示元素的大小是多少,這個(gè)單位就是設(shè)備獨(dú)立像素(
Device Independent Pixels)簡稱
DIP或
DP。上面我們說,列表的寬度為
300個(gè)像素,實(shí)際上我們可以說:列表的寬度為
300個(gè)設(shè)備獨(dú)立像素。
?
?
打開chrome的開發(fā)者工具,我們可以模擬各個(gè)手機(jī)型號的顯示情況,每種型號上面會顯示一個(gè)尺寸,比如
iPhone X顯示的尺寸是
375x812,實(shí)際
iPhone X的分辨率會比這高很多,這里顯示的就是設(shè)備獨(dú)立像素。
?
?
3.1 設(shè)備像素比
設(shè)備像素比
device pixel ratio簡稱
dpr,即物理像素和設(shè)備獨(dú)立像素的比值。
在web中,瀏覽器為我們提供了
window.devicePixelRatio來幫助我們獲取
dpr。
在
css中,可以使用媒體查詢
min-device-pixel-ratio,區(qū)分
dpr:
@media (-webkit-min-device-pixel-ratio: 2),(min-device-pixel-ratio: 2){ } 復(fù)制代碼
在
React Native中,我們也可以使用
PixelRatio.get()來獲取
DPR。
當(dāng)然,上面的規(guī)則也有例外,
iPhone 6、7、8 Plus的實(shí)際物理像素是
1080 x 1920,在開發(fā)者工具中我們可以看到:它的設(shè)備獨(dú)立像素是
414 x 736,設(shè)備像素比為
3,設(shè)備獨(dú)立像素和設(shè)備像素比的乘積并不等于
1080 x 1920,而是等于
1242 x 2208。
實(shí)際上,手機(jī)會自動(dòng)把
1242 x 2208個(gè)像素點(diǎn)塞進(jìn)
1080 * 1920個(gè)物理像素點(diǎn)來渲染,我們不用關(guān)心這個(gè)過程,而
1242 x 2208被稱為屏幕的
設(shè)計(jì)像素。我們開發(fā)過程中也是以這個(gè)
設(shè)計(jì)像素為準(zhǔn)。
實(shí)際上,從蘋果提出視網(wǎng)膜屏幕開始,才出現(xiàn)設(shè)備像素比這個(gè)概念,因?yàn)樵谶@之前,移動(dòng)設(shè)備都是直接使用物理像素來進(jìn)行展示。
緊接著,
Android同樣使用了其他的技術(shù)方案來實(shí)現(xiàn)
DPR大于
1的屏幕,不過原理是類似的。由于
Android屏幕尺寸非常多、分辨率高低跨度非常大,不像蘋果只有它自己的幾款固定設(shè)備、尺寸。所以,為了保證各種設(shè)備的顯示效果,
Android按照設(shè)備的像素密度將設(shè)備分成了幾個(gè)區(qū)間:
?
?
當(dāng)然,所有的
Android設(shè)備不一定嚴(yán)格按照上面的分辨率,每個(gè)類型可能對應(yīng)幾種不同分辨率,所以,每個(gè)
Android手機(jī)都能根據(jù)給定的區(qū)間范圍,確定自己的
DPR,從而擁有類似的顯示。當(dāng)然,僅僅是類似,由于各個(gè)設(shè)備的尺寸、分辨率上的差異,設(shè)備獨(dú)立像素也不會完全相等,所以各種
Android設(shè)備仍然不能做到在展示上完全相等。
3.2 移動(dòng)端開發(fā)
在
iOS、
Android和
React Native開發(fā)中樣式單位其實(shí)都使用的是設(shè)備獨(dú)立像素。
iOS的尺寸單位為
pt,
Android的尺寸單位為
dp,
React Native中沒有指定明確的單位,它們其實(shí)都是設(shè)備獨(dú)立像素
dp。
在使用
React Native開發(fā)
App時(shí),
UI給我們的原型圖一般是基于
iphone6的像素給定的。
為了適配所有機(jī)型,我們在寫樣式時(shí)需要把物理像素轉(zhuǎn)換為設(shè)備獨(dú)立像素:例如:如果給定一個(gè)元素的高度為
200px(這里的
px指物理像素,非
CSS像素),
iphone6的設(shè)備像素比為
2,我們給定的
height應(yīng)為
200px/2=100dp。
當(dāng)然,最好的是,你可以和設(shè)計(jì)溝通好,所有的
UI圖都按照設(shè)備獨(dú)立像素來出。
我們還可以在代碼(
React Native)中進(jìn)行
px和
dp的轉(zhuǎn)換:
import {PixelRatio } from "react-native"; const dpr = PixelRatio.get(); /** * px轉(zhuǎn)換為dp */ export function pxConvertTodp(px) { return px / dpr; } /** * dp轉(zhuǎn)換為px */ export function dpConvertTopx(dp) { return PixelRatio.getPixelSizeForLayoutSize(dp); } 復(fù)制代碼
3.3 WEB端開發(fā)
在寫
CSS時(shí),我們用到最多的單位是
px,即
CSS像素,當(dāng)頁面縮放比例為
100%時(shí),一個(gè)
CSS像素等于一個(gè)設(shè)備獨(dú)立像素。
但是
CSS像素是很容易被改變的,當(dāng)用戶對瀏覽器進(jìn)行了放大,
CSS像素會被放大,這時(shí)一個(gè)
CSS像素會跨越更多的物理像素。
頁面的縮放系數(shù) = CSS像素 / 設(shè)備獨(dú)立像素。
3.4 關(guān)于屏幕
這里多說兩句
Retina屏幕,因?yàn)槲以诤芏辔恼轮锌吹綄?p>Retina屏幕的誤解。
Retina屏幕只是蘋果提出的一個(gè)營銷術(shù)語:
在普通的使用距離下,人的肉眼無法分辨單個(gè)的像素點(diǎn)。
為什么強(qiáng)調(diào)
普通的使用距離下呢?我們來看一下它的計(jì)算公式:
a代表人眼視角,
h代表像素間距,
d代表肉眼與屏幕的距離,符合以上條件的屏幕可以使肉眼看不見單個(gè)物理像素點(diǎn)。
它不能單純的表達(dá)分辨率和
PPI,只能一種表達(dá)視覺效果。
讓多個(gè)物理像素渲染一個(gè)獨(dú)立像素只是
Retina屏幕為了達(dá)到效果而使用的一種技術(shù)。而不是所有
DPR > 1的屏幕就是
Retina屏幕。
比如:給你一塊超大尺寸的屏幕,即使它的
PPI很高,
DPR也很高,在近距離你也能看清它的像素點(diǎn),這就不算
Retina屏幕。
?
?
我們經(jīng)常見到用
K和
P這個(gè)單位來形容屏幕:
P代表的就是屏幕縱向的像素個(gè)數(shù),
1080P即縱向有
1080個(gè)像素,分辨率為
1920X1080的屏幕就屬于
1080P屏幕。
我們平時(shí)所說的高清屏其實(shí)就是屏幕的物理分辨率達(dá)到或超過
1920X1080的屏幕。
K代表屏幕橫向有幾個(gè)
1024個(gè)像素,一般來講橫向像素超過
2048就屬于
2K屏,橫向像素超過
4096就屬于
4K屏。
四、視口
視口(
viewport)代表當(dāng)前可見的計(jì)算機(jī)圖形區(qū)域。在
Web瀏覽器術(shù)語中,通常與瀏覽器窗口相同,但不包括瀏覽器的
UI, 菜單欄等——即指你正在瀏覽的文檔的那一部分。
一般我們所說的視口共包括三種:布局視口、視覺視口和理想視口,它們在屏幕適配中起著非常重要的作用。
4.1 布局視口
?
?
布局視口(
layout viewport):當(dāng)我們以百分比來指定一個(gè)元素的大小時(shí),它的計(jì)算值是由這個(gè)元素的包含塊計(jì)算而來的。當(dāng)這個(gè)元素是最頂級的元素時(shí),它就是基于布局視口來計(jì)算的。
所以,布局視口是網(wǎng)頁布局的基準(zhǔn)窗口,在
PC瀏覽器上,布局視口就等于當(dāng)前瀏覽器的窗口大小(不包括
borders 、
margins、滾動(dòng)條)。
在移動(dòng)端,布局視口被賦予一個(gè)默認(rèn)值,大部分為
980px,這保證
PC的網(wǎng)頁可以在手機(jī)瀏覽器上呈現(xiàn),但是非常小,用戶可以手動(dòng)對網(wǎng)頁進(jìn)行放大。
我們可以通過調(diào)用
document.documentElement.clientWidth / clientHeight來獲取布局視口大小。
4.2 視覺視口
?
?
視覺視口(
visual viewport):用戶通過屏幕真實(shí)看到的區(qū)域。
視覺視口默認(rèn)等于當(dāng)前瀏覽器的窗口大小(包括滾動(dòng)條寬度)。
當(dāng)用戶對瀏覽器進(jìn)行縮放時(shí),不會改變布局視口的大小,所以頁面布局是不變的,但是縮放會改變視覺視口的大小。
例如:用戶將瀏覽器窗口放大了
200%,這時(shí)瀏覽器窗口中的
CSS像素會隨著視覺視口的放大而放大,這時(shí)一個(gè)
CSS像素會跨越更多的物理像素。
所以,布局視口會限制你的
CSS布局而視覺視口決定用戶具體能看到什么。
我們可以通過調(diào)用
window.innerWidth / innerHeight來獲取視覺視口大小。
4.3 理想視口
?
?
布局視口在移動(dòng)端展示的效果并不是一個(gè)理想的效果,所以理想視口(
ideal viewport)就誕生了:網(wǎng)站頁面在移動(dòng)端展示的理想大小。
如上圖,我們在描述設(shè)備獨(dú)立像素時(shí)曾使用過這張圖,在瀏覽器調(diào)試移動(dòng)端時(shí)頁面上給定的像素大小就是理想視口大小,它的單位正是設(shè)備獨(dú)立像素。
上面在介紹
CSS像素時(shí)曾經(jīng)提到
頁面的縮放系數(shù) = CSS像素 / 設(shè)備獨(dú)立像素,實(shí)際上說
頁面的縮放系數(shù) = 理想視口寬度 / 視覺視口寬度更為準(zhǔn)確。
所以,當(dāng)頁面縮放比例為
100%時(shí),
CSS像素 = 設(shè)備獨(dú)立像素,
理想視口 = 視覺視口。
我們可以通過調(diào)用
screen.width / height來獲取理想視口大小。
4.4 Meta viewport
元素表示那些不能由其它
HTML元相關(guān)元素之一表示的任何元數(shù)據(jù)信息,它可以告訴瀏覽器如何解析頁面。
我們可以借助
元素的
viewport來幫助我們設(shè)置視口、縮放等,從而讓移動(dòng)端得到更好的展示效果。
復(fù)制代碼
上面是
viewport的一個(gè)配置,我們來看看它們的具體含義:
Value |
可能值 |
描述 |
---|---|---|
width |
正整數(shù)或 device-width |
以 pixels(像素)為單位, 定義布局視口的寬度。 |
height |
正整數(shù)或 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 |
一個(gè)布爾值( yes或者 no) |
如果設(shè)置為 no,用戶將不能放大或縮小網(wǎng)頁。默認(rèn)值為 yes。 |
4.5 移動(dòng)端適配
為了在移動(dòng)端讓頁面獲得更好的顯示效果,我們必須讓布局視口、視覺視口都盡可能等于理想視口。
device-width就等于理想視口的寬度,所以設(shè)置
width=device-width就相當(dāng)于讓布局視口等于理想視口。
由于
initial-scale = 理想視口寬度 / 視覺視口寬度,所以我們設(shè)置
initial-scale=1;就相當(dāng)于讓視覺視口等于理想視口。
這時(shí),1個(gè)
CSS像素就等于1個(gè)設(shè)備獨(dú)立像素,而且我們也是基于理想視口來進(jìn)行布局的,所以呈現(xiàn)出來的頁面布局在各種設(shè)備上都能大致相似。
4.6 縮放
上面提到
width可以決定布局視口的寬度,實(shí)際上它并不是布局視口的唯一決定性因素,設(shè)置
initial-scale也有肯能影響到布局視口,因?yàn)椴季忠暱趯挾热〉氖?p>width和視覺視口寬度的最大值。
例如:若手機(jī)的理想視口寬度為
400px,設(shè)置
width=device-width,
initial-scale=2,此時(shí)
視覺視口寬度 = 理想視口寬度 / initial-scale即
200px,布局視口取兩者最大值即
device-width
400px。
若設(shè)置
width=device-width,
initial-scale=0.5,此時(shí)
視覺視口寬度 = 理想視口寬度 / initial-scale即
800px,布局視口取兩者最大值即
800px。
4.7 獲取瀏覽器大小
瀏覽器為我們提供的獲取窗口大小的
API有很多,下面我們再來對比一下:
?
window.innerHeight:獲取瀏覽器視覺視口高度(包括垂直滾動(dòng)條)。
window.outerHeight:獲取瀏覽器窗口外部的高度。表示整個(gè)瀏覽器窗口的高度,包括側(cè)邊欄、窗口鑲邊和調(diào)正窗口大小的邊框。
window.screen.Height:獲取獲屏幕取理想視口高度,這個(gè)數(shù)值是固定的,
設(shè)備的分辨率/設(shè)備像素比
window.screen.availHeight:瀏覽器窗口可用的高度。
document.documentElement.clientHeight:獲取瀏覽器布局視口高度,包括內(nèi)邊距,但不包括垂直滾動(dòng)條、邊框和外邊距。
document.documentElement.offsetHeight:包括內(nèi)邊距、滾動(dòng)條、邊框和外邊距。
document.documentElement.scrollHeight:在不使用滾動(dòng)條的情況下適合視口中的所有內(nèi)容所需的最小寬度。測量方式與
clientHeight相同:它包含元素的內(nèi)邊距,但不包括邊框,外邊距或垂直滾動(dòng)條。
五、1px問題
為了適配各種屏幕,我們寫代碼時(shí)一般使用設(shè)備獨(dú)立像素來對頁面進(jìn)行布局。
而在設(shè)備像素比大于
1的屏幕上,我們寫的
1px實(shí)際上是被多個(gè)物理像素渲染,這就會出現(xiàn)
1px在有些屏幕上看起來很粗的現(xiàn)象。
5.1 border-image
基于
media查詢判斷不同的設(shè)備像素比給定不同的
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; } } 復(fù)制代碼
5.2 background-image
和
border-image類似,準(zhǔn)備一張符合條件的邊框背景圖,模擬在背景上。
.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; } } 復(fù)制代碼
上面兩種都需要多帶帶準(zhǔn)備圖片,而且圓角不是很好處理,但是可以應(yīng)對大部分場景。
5.3 偽類 + transform
基于
media查詢判斷不同的設(shè)備像素比對線條進(jìn)行縮放:
.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); } } 復(fù)制代碼
這種方式可以滿足各種場景,如果需要滿足圓角,只需要給偽類也加上
border-radius即可。
5.4 svg
上面我們
border-image和
background-image都可以模擬
1px邊框,但是使用的都是位圖,還需要外部引入。
借助
PostCSS的
postcss-write-svg我們能直接使用
border-image和
background-image創(chuàng)建
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; } 復(fù)制代碼
編譯后:
.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; } 復(fù)制代碼
上面的方案是大漠在他的文章中推薦使用的,基本可以滿足所有場景,而且不需要外部引入,這是我個(gè)人比較喜歡的一種方案。
5.5 設(shè)置viewport
通過設(shè)置縮放,讓
CSS像素等于真正的物理像素。
例如:當(dāng)設(shè)備像素比為
3時(shí),我們將頁面縮放
1/3倍,這時(shí)
1px等于一個(gè)真正的屏幕像素。
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); 復(fù)制代碼
實(shí)際上,上面這種方案是早先
flexible采用的方案。
當(dāng)然,這樣做是要付出代價(jià)的,這意味著你頁面上所有的布局都要按照物理像素來寫。這顯然是不現(xiàn)實(shí)的,這時(shí),我們可以借助
flexible或
vw、vh來幫助我們進(jìn)行適配。
六、移動(dòng)端適配方案
盡管我們可以使用設(shè)備獨(dú)立像素來保證各個(gè)設(shè)備在不同手機(jī)上顯示的效果類似,但這并不能保證它們顯示完全一致,我們需要一種方案來讓設(shè)計(jì)稿得到更完美的適配。
6.1 flexible方案
flexible方案是阿里早期開源的一個(gè)移動(dòng)端適配解決方案,引用
flexible后,我們在頁面上統(tǒng)一使用
rem來布局。
它的核心代碼非常簡單:
// set 1rem = viewWidth / 10 function setRemUnit () { var rem = docEl.clientWidth / 10 docEl.style.fontSize = rem + "px" } setRemUnit(); 復(fù)制代碼
rem 是相對于
html節(jié)點(diǎn)的
font-size來做計(jì)算的。
我們通過設(shè)置
document.documentElement.style.fontSize就可以統(tǒng)一整個(gè)頁面的布局標(biāo)準(zhǔn)。
上面的代碼中,將
html節(jié)點(diǎn)的
font-size設(shè)置為頁面
clientWidth(布局視口)的
1/10,即
1rem就等于頁面布局視口的
1/10,這就意味著我們后面使用的
rem都是按照頁面比例來計(jì)算的。
這時(shí),我們只需要將
UI出的圖轉(zhuǎn)換為
rem即可。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/6642.html
摘要:需要注意,上面的尺寸都是屏幕對角線的長度英寸縮寫為在荷蘭語中的本意是大拇指,一英寸就是指甲底部普通人拇指的寬度。由于手機(jī)尺寸為手機(jī)對角線的長度,我們通常使用如下的方法計(jì)算的為那它每英寸約含有個(gè)物理像素點(diǎn)。 導(dǎo)讀 移動(dòng)端適配,是我們在開發(fā)中經(jīng)常會遇到的,這里面可能會遇到非常多的問題: 1px問題 UI圖完美適配方案 iPhoneX適配方案 橫屏適配 高清屏圖片模糊問題 ... ...
摘要:需要注意,上面的尺寸都是屏幕對角線的長度英寸縮寫為在荷蘭語中的本意是大拇指,一英寸就是指甲底部普通人拇指的寬度。由于手機(jī)尺寸為手機(jī)對角線的長度,我們通常使用如下的方法計(jì)算的為那它每英寸約含有個(gè)物理像素點(diǎn)。 導(dǎo)讀 移動(dòng)端適配,是我們在開發(fā)中經(jīng)常會遇到的,這里面可能會遇到非常多的問題: 1px問題 UI圖完美適配方案 iPhoneX適配方案 橫屏適配 高清屏圖片模糊問題 ... ...
摘要:本文主要介紹一些響應(yīng)式布局容易忽略但又很重要的知識點(diǎn)。單位不僅僅可以用來設(shè)置字號,還可以設(shè)置任何盒模型的屬性,比如有一點(diǎn)優(yōu)勢就是可以和媒體查詢配合,實(shí)現(xiàn)響應(yīng)式布局運(yùn)用場景如果我們做的頁面只在移動(dòng)端訪問,這是因?yàn)椴患嫒莸桶姹镜臑g覽器。 一、前言 響應(yīng)式Web設(shè)計(jì)可以讓一個(gè)網(wǎng)站同時(shí)適配多種設(shè)備和多個(gè)屏幕,可以讓網(wǎng)站的布局和功能隨用戶的使用環(huán)境(屏幕大小、輸入方式、設(shè)備/瀏覽器能力)而變化。...
摘要:本文主要介紹一些響應(yīng)式布局容易忽略但又很重要的知識點(diǎn)。單位不僅僅可以用來設(shè)置字號,還可以設(shè)置任何盒模型的屬性,比如有一點(diǎn)優(yōu)勢就是可以和媒體查詢配合,實(shí)現(xiàn)響應(yīng)式布局運(yùn)用場景如果我們做的頁面只在移動(dòng)端訪問,這是因?yàn)椴患嫒莸桶姹镜臑g覽器。 一、前言 響應(yīng)式Web設(shè)計(jì)可以讓一個(gè)網(wǎng)站同時(shí)適配多種設(shè)備和多個(gè)屏幕,可以讓網(wǎng)站的布局和功能隨用戶的使用環(huán)境(屏幕大小、輸入方式、設(shè)備/瀏覽器能力)而變化。...
摘要:本文主要介紹一些響應(yīng)式布局容易忽略但又很重要的知識點(diǎn)。單位不僅僅可以用來設(shè)置字號,還可以設(shè)置任何盒模型的屬性,比如有一點(diǎn)優(yōu)勢就是可以和媒體查詢配合,實(shí)現(xiàn)響應(yīng)式布局運(yùn)用場景如果我們做的頁面只在移動(dòng)端訪問,這是因?yàn)椴患嫒莸桶姹镜臑g覽器。 一、前言 響應(yīng)式Web設(shè)計(jì)可以讓一個(gè)網(wǎng)站同時(shí)適配多種設(shè)備和多個(gè)屏幕,可以讓網(wǎng)站的布局和功能隨用戶的使用環(huán)境(屏幕大小、輸入方式、設(shè)備/瀏覽器能力)而變化。...
閱讀 2839·2021-11-24 09:39
閱讀 4138·2021-10-27 14:19
閱讀 2056·2021-08-12 13:25
閱讀 2346·2019-08-29 17:07
閱讀 1122·2019-08-29 13:44
閱讀 1074·2019-08-26 12:17
閱讀 470·2019-08-23 17:16
閱讀 2057·2019-08-23 16:46