1. 程式人生 > >單屏頁面響應式適配玩法

單屏頁面響應式適配玩法

首先瞅一下效果圖

接著就是思考怎麼做,我的想法如下圖。

image

把公共的 頁頭頁尾導航欄邊框 放到最頂層,比方說設定層級為 999,其他每個獨立頁則放在下面,然後切換頁面的時候更新獨立頁的層級以達到效果圖的效果(當然不能超過最頂層)。

適配

上面的方式已經把效果做出來了,接下來就是響應式適配了。

1、Mac OS + Chrome

先考慮一下我自己的系統及顯示器,

MacBook Pro 1440 x 900 + 外設 hp 1920 x 1080

也就是說 Chrome 的網頁可視區高度大概為: 900(或1080) - 180 = 720px

180 = 60 + 20 + 100

123 60:MAC桌面程式塢動態尺寸,60可能是我常用的尺寸吧,那就先這個20:MAC桌面最頂部icon放置欄高度100:Chrome標籤頁高度+位址列高度+書籤欄高度

2、Windows + Chrome

然後我們再看看 Windows + Chrome 的情況,以 1366 x 768 為例,

Chrome 的網頁可視區高度大概為 768 - 150 = 618px

150 = 40 + 110

JavaScript
12 40:Windows桌面底部程式塢尺寸110:Chrome標籤頁高度+位址列高度+書籤欄高度

3、總結上面兩點

  1. 以上兩點的高度計算通過截圖獲得,可能會有些許誤差。
  2. 所以不管在哪種系統下,瀏覽器的寬度與解析度是保持一致的(程式塢在底部的時候,程式塢在左右兩邊一般情況對寬度沒有影響),高度則根據系統及瀏覽器的不同各有不同,比方說 Safari 沒有書籤高度。
  3. 不同系統加瀏覽器佔用的最高高度約為 180,最小約為 0(全屏的時候)

4、主流系統解析度尺寸

然後我們看下當前主流系統及解析度有哪些

PC & MAC & Chrome

JavaScript
123456789101112 常用1280x8001366x1024(IPad Pro)1440x9001680x10501600x9001920x12002560x1440更高忽略2880x16203200x18005120x2880

PC & Windows & Chrome (或 PC & MAC & Chrome & 外設顯示器)

JavaScript
12345 1280x720/10241366x7681440×9001600x9001920x1080

Mobile & Android

JavaScript
123 360x480412x732待補充

Mobile & IOS

JavaScript
123 IPhone6:375x667IPhone6 Plus:414x736IPhone X:375x812

不上不下的 IPad:

JavaScript
1 768x1024

5、分析

我們以寬度 1024 及以下算作移動端,以上算作 PC 端,所以兩種選擇

  1. 移動端適配一個移動端頁面,PC 端適配一個 PC 端頁面。
  2. 設計之初就想好一個頁面適配兩端,當然這個設計稿需要比較符合適配兩端的條件。

6、別人適配是怎麼做的?

貼幾個錄製的視訊~

視訊1

視訊2

視訊3

所以,單屏頁面最好頁面內容言簡意賅,設計層面傾向於水平垂直都居中的情況,是最適合做好這個頁面的,並且在各種尺寸變化的情況下能比較良好地展示UI,且開發成本也比較合理。

7、自身情況及實現

我們是分兩個頁面做的,先看一下 PC 端設計稿

結合動畫的展現形式,其實並不是很理想做響應式,但還是要適配。

本來想用 rem 做適配的,但是 rem 需要些寫很多個匹配,即下面的程式碼

CSS
1234567891011 @media all and (max-width: 1024px) {  html, body {    font-size: 10px;}}@media all and (max-width: 1366px) {  html, body {    font-size: 12px;}}//168019202560

然後有個問題就是,@media 是根據 width 的變化來匹配的,完全按照桌面解析度來顯示是沒問題的,不過高度隨便調節一下(變小),而寬度還是很寬,這時候頁面底部的部分文字就會溢位被隱藏掉。

我們不需要考慮更低端的瀏覽器,所以可以使用比較前沿的特性,如 pointer-events 等特性。

所以使用 vh 做適配方案,vh 是什麼單位詳情可以看下這篇文章,這裡做個簡單介紹。

JavaScript
12 vw:相對於瀏覽器可視區的寬度1vw=瀏覽器可視區寬度的1%vh:相對於瀏覽器可視區的高度1vh=瀏覽器可視區高度的1%

也就是說 100vh 實際上等於瀏覽器可視區的高度,所以 pxvh 的換算我們舉個例子說明一下(一個很簡單的數學換算)。假設瀏覽器可視區高度為 720px,某個元素的寬度為 300px,那應該寫成多少 vh 才與 300px 相等呢,如下。

JavaScript
1 300÷(720÷100)41.666

比如設計稿為 1920x1080(單屏設計高度應該更小一點,如適配第一節所說),可以寫個 CSS 預處理函式,這樣方便直接使用設計稿的尺寸,以 Sass 為例如下。

Sass
1234567 <a href="http://www.jobbole.com/members/wx2980501052">@function</a> vh( $value ) {<a href="http://www.jobbole.com/members/wx1409399284">@return</a> ( $value / 1080 / 100 ) + vh;}或者<a href="http://www.jobbole.com/members/wx2980501052">@function</a> vw( $value ) {<a href="http://www.jobbole.com/members/wx1409399284">@return</a> ( $value / 1920 / 100 ) + vw;}

然後,300px 可以無縫寫成 vh(300)vw(300)

so… 對於我們的頁面選擇 vh 一舉兩得,不用寫很多 rem 匹配,也不會出現溢位的問題。

因為高度變矮,內容的尺寸會隨之變小,而頁面是 1190 寬,水平居中佈局,所以當只改變瀏覽器寬度的情況下,不會出現寬度變化溢位問題(除非解析度超大,然後高度居很高,只把寬度縮很小的情況,這個下面會說到)。寫完後在上面列舉的主流解析度下一一測試通過。

看看效果(當然這個是最終效果,只改變寬度的拉伸適配在最後會說):

視訊

8、特殊場景

這裡就是剛剛說到的 解析度超大,然後高度居很高,只把寬度縮很小的情況,因為設計稿是長寬比例為橫向矩形,所以明顯與用長寬比為豎向的矩形來看頁面是背道而馳的。

view

委屈委屈,但還是要相容下,至少看起來要顯示正常。

8.1、嘗試 rem + vh 方案

一開始想的是 rem + vh 結合使用,根元素 html 使用 vh,其他單位則使用 rem,然後找到有問題的寬高比,通過 @media 方式設定 htmlvw 來達到適配。

事實是,rem 縮小到一定值就不會再縮小了,這個跟瀏覽器對字型大小限制為最小 12px 一樣,看個例子。

rem min

根字型小於 12px 以後,rem 對應的值則都是設定的倍數乘以 12;設定根字型為 vh, vw 單位同理,rem 會在 vh, vw 換算達到 12 以後就不再改變。

PPPS: 是不是有點坑,應該字型的屬性最小值為 12,而其他屬性的值沒有控制才對

所以,如果使用 rem + vh 方案,在介面縮小到一定尺寸後繼續縮小,有些值達到最小值固定不變,而有些值仍在變小,UI 的展示就變得混亂。

8.2、落地方案,vh + vw + JavaScript 計算

而直接在元素的屬性值上設定為 vh 或 vw,所有的值都會實時變動,沒有最小值(除了屬性為字型有最小值),這樣就最大程度減少 UI 變亂的情況了,除非縮到很小很小,那就…(此處省略 1000 個字)。

於是乎,現在的想法是

  1. 在原來以 vh 為基礎的情況下,拷貝所有帶 vh 單位的程式碼,把 vh 換成 vw,當然這些改動都在一個比如叫 .vw-mode 的類下面,基本上可以無縫遷移,只需替換 vh 函式名即可。
  2. .vw-mode 下的內容設定為上下居中。
  3. 通過 JS 計算,當可視區比例為豎向比例時,則在頂層元素加上 .vw-mode 類名,當比例為橫向比例時,則去掉 .vw-mode 類名。

大致的程式碼如下

CSS

CSS
1234567891011 .homepage.vw-mode {font-size:vw(14);.com-width {width:vw(1190);}.hp-header {padding-top:vw(30);//...更多程式碼}//...更多程式碼}

JS

JavaScript
123456789 this.resizeHandler=()=>{constclientWidth=document.documentElement.clientWidthconstclientHeight=document.documentElement.clientHeight// 當長寬比為豎向比例時constisVerticalRatio=clientWidth/clientHeight<1370/890$homepageElem.classList[isVerticalRatio?'add':'remove']('vw-mode')}this.resizeHandler()window.addEventListener('resize',this.resizeHandler)

最後的結果就是上面那個 GIF 效果圖了。

9、移動端

移動端使用者是沒法操作瀏覽器的,所以基本上都是標準的長寬比,用 vh 最合適不過了,或 vw

10、最後

體驗瀏覽器:Chrome、Safari 新版,其他瀏覽器暫不支援