邏輯畫素和物理畫素
邏輯畫素也叫『裝置獨立畫素』,即CSS畫素,例如,iPhone 6的邏輯畫素是375px
物理畫素是裝置螢幕實際擁有的畫素點,裝置生產出來,畫素就確定了,例如,iPhone 6的物理畫素是750px
在iPhone 6下,物理畫素是邏輯畫素的2倍,用『裝置畫素比』表示該值,即物理畫素除以邏輯畫素的值,透過window.devicePixelRatio
獲取裝置畫素比
viewport視口
一般移動裝置的瀏覽器都預設設定了一個viewport元標籤,定義一個虛擬的佈局視口(layout viewport),用於解決早期的 頁面在手機上顯示的問題。iOS, Android 基本都將這個視口解析度設定為 980px,所以PC上的網頁基本能在手機上呈現,只不 過元素看上去很小,一般預設可以透過手動縮放網頁。
為了解決這個問題,可透過meta標籤來修改視口的尺寸大小
<meta name="viewport" content="width=device-width, initial-scale=1.0" minimum-scale="1.0" maximum-scale="1.0" user-scalable="no">
width=device-width
表示視口寬度為裝置的寬,也就是邏輯畫素的大小initial-scale=1.0
表示初始縮放比例為1,即 正常大小maximum-scale
表示放大的最大比例minimum-scale
表示縮小的最小比例user-scalable
表示是否允許使用者手動縮放頁面,預設yes
window.innerWidth
可以獲取裝置的寬度。
document.documentElement.clientWidth
可以獲取視口的寬度。
當viewport的width
的值是device-width
,裝置的寬度等於視口的寬度
rem單位
CSS中,rem
表示root元素的字型大小。(root元素即html元素)
即,1rem
等於root元素的字型大小,對於大多數的瀏覽器,預設值是16px
。
html {
font-size: 12px; /* 此時, 1rem = 12px */
}
.box {
width: 2rem; /* 2x12=24px */
}
不同的裝置的視口是不同的,所以在不同的裝置中root元素的font size值也不同,以此來達到縮放的效果。
計算root元素的font size有兩種方法:
- 利用JS計算根元素的font size值
- vw
JavaScript計算rem值
以iPhone6為基準,螢幕寬度為375,root元素的font size計算如下:
function onWindowResize() {
let documentElement = document.documentElement;
let viewportWidth = documentElement.clientWidth;
// 在CSS中計算rem的時候也是以37.5px為基準
documentElement.style.fontSize = viewportWidth / 10 + 'px';
documentElement.setAttribute('data-dpr', window.devicePixelRatio);
}
window.addEventListener('resize', onWindowResize);
window.addEventListener('load', onWindowResize);
通常移動端UI設計稿按照iPhone6的物理畫素為基準進行設計,即750px,在量取尺寸的時候,需要除以2才能適配頁面中的css邏輯畫素
@function px2rem($px) {
$base: 37.5;
@return calc($px / 2 / $base) * 1rem;
}
37.5px
就是基準值,和JS程式碼中的保持一致。假如A元素在設計稿上的寬度是120px
,那麼在iPhone6上就是1.6rem
。
當手機切換到iPhone XR時,root元素的font size的值就變成了41.4px
,因為A元素的寬度是1.6rem
,那麼它的實際寬度就是41.4 x 1.6 = 66.24
,這就起到了縮放效果。
總結兩點:
- 動態計算
html
的font-size
值 - 在CSS中將px轉為rem
rem + vw
利用vw
計算root元素的font size值就不需要用JS去動態計算根元素的字型大小。其他佈局元素用rem做單位。
750px的設計稿,root元素字號100px,換算成vw,就是100/750 = 13.33333333vw;
透過CSS計算函式自動計算:
:root {
--psd: 750;
--root-font-size: 100;
}
html {
font-size: calc(100vw / var(--psd) * var(--root-font-size))
}
@media screen and (min-width: 750px) {
html {
font-size: 100px;
}
body {
width: 750px;
margin-left: auto;
margin-right: auto;
}
}
最後,設計稿元素的大小直接除以100換算成rem單位
@function pxtorem($px) {
@return calc($px / 100) * 1rem;
}
另一種計算方式是按照手機尺寸計算,以iPhone 6為準,就是375px,在量取尺寸時需要除以2,因為設計稿是750px的
// 按照iPhone 6的邏輯畫素計算,即375px
100vw = 375px => 1px = 100/375 = 0.26666667vw;
100px = 0.26666667 * 100 = 26.66666667vw;
vw
使用vw佈局就不需要去設定根元素的font size了
頁面所有元素都用vw做單位。設計稿750px=100vw
,
$psd: 750;
/**
$px $vw
------------- === ------------
$psd 100vw
*/
@function pxtovw($px) {
@return calc($px / $psd) * 100vw;
}