Web移動端佈局

RyanZ0523發表於2024-04-15

邏輯畫素和物理畫素

邏輯畫素也叫『裝置獨立畫素』,即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,這就起到了縮放效果。

總結兩點:

  • 動態計算htmlfont-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;
}

相關文章