單屏頁面響應式適配玩法
首先瞅一下效果圖
接著就是思考怎么做,我的想法如下圖。
把公共的 頁頭 、頁腳、導航欄、邊框 放到最頂層,比方說設置層級為 999,其他每個獨立頁則放在下面,然后切換頁面的時候更新獨立頁的層級以達到效果圖的效果(當然不能超過最頂層)。
適配
上面的方式已經把效果做出來了,接下來就是響應式適配了。
1、Mac OS + Chrome
先考慮一下我自己的系統及顯示器,
MacBook Pro 1440 x 900 + 外設 hp 1920 x 1080
也就是說 Chrome 的網頁可視區高度大概為: 900(或1080) - 180 = 720px
180 = 60 + 20 + 100
- 60: MAC 桌面程序塢動態尺寸,60 可能是我常用的尺寸吧,那就先這個
- 20: MAC 桌面最頂部 icon 放置欄高度
- 100: Chrome 標簽頁高度 + 地址欄高度 + 書簽欄高度
2、Windows + Chrome
然后我們再看看 Windows + Chrome 的情況,以 1366 x 768 為例,
Chrome 的網頁可視區高度大概為 768 - 150 = 618px
150 = 40 + 110
- 40: Windows 桌面底部程序塢尺寸
- 110: Chrome 標簽頁高度 + 地址欄高度 + 書簽欄高度
3、總結上面兩點
- 以上兩點的高度計算通過截圖獲得,可能會有些許誤差。
- 所以不管在哪種系統下,瀏覽器的寬度與分辨率是保持一致的(程序塢在底部的時候,程序塢在左右兩邊一般情況對寬度沒有影響),高度則根據系統及瀏覽器的不同各有不同,比方說 Safari 沒有書簽高度。
- 不同系統加瀏覽器占用的***高度約為 180,最小約為 0(全屏的時候)
4、主流系統分辨率尺寸
然后我們看下當前主流系統及分辨率有哪些
PC & MAC & Chrome
常用
- 1280 x 800
- 1366 x 1024 (IPad Pro)
- 1440 x 900
- 1680 x 1050
- 1600 x 900
- 1920 x 1200
- 2560 x 1440
更高忽略
- 2880 x 1620
- 3200 x 1800
- 5120 x 2880
PC & Windows & Chrome (或 PC & MAC & Chrome & 外設顯示器)
- 1280 x 720/1024
- 1366 x 768
- 1440 × 900
- 1600 x 900
- 1920 x 1080
- 360 x 480
- 412 x 732
- 待補充
Mobile & IOS
- IPhone 6: 375 x 667
- IPhone 6 Plus: 414 x 736
- IPhone X: 375 x 812
不上不下的 IPad:
- 768 x 1024
5、分析
我們以寬度 1024 及以下算作移動端,以上算作 PC 端,所以兩種選擇
- 移動端適配一個移動端頁面,PC 端適配一個 PC 端頁面。
- 設計之初就想好一個頁面適配兩端,當然這個設計稿需要比較符合適配兩端的條件。
6、別人適配是怎么做的?
貼個錄制的視頻~
所以,單屏頁面***頁面內容言簡意賅,設計層面傾向于水平垂直都居中的情況,是最適合做好這個頁面的,并且在各種尺寸變化的情況下能比較良好地展示UI,且開發成本也比較合理。
7、自身情況及實現
我們是分兩個頁面做的,先看一下 PC 端設計稿:
結合動畫的展現形式,其實并不是很理想做響應式,但還是要適配。
本來想用 rem 做適配的,但是 rem 需要些寫很多個匹配,即下面的代碼
- @media all and (max-width: 1024px) {
- html, body {
- font-size: 10px;
- }
- }
- @media all and (max-width: 1366px) {
- html, body {
- font-size: 12px;
- }
- }
- // 1680 1920 2560 等
然后有個問題就是,@media 是根據 width 的變化來匹配的,完全按照桌面分辨率來顯示是沒問題的,不過高度隨便調節一下(變小),而寬度還是很寬,這時候頁面底部的部分文本就會溢出被隱藏掉。
我們不需要考慮更低端的瀏覽器,所以可以使用比較前沿的特性,如 pointer-events 等特性。
所以使用 vh 做適配方案,vh 是什么單位詳情可以自己查閱一下文檔,這里做個簡單介紹。
- vw: 相對于瀏覽器可視區的寬度 1vw = 瀏覽器可視區寬度的 1%
- vh: 相對于瀏覽器可視區的高度 1vh = 瀏覽器可視區高度的 1%
也就是說 100vh 實際上等于瀏覽器可視區的高度,所以 px 與 vh 的換算我們舉個例子說明一下(一個很簡單的數學換算)。假設瀏覽器可視區高度為 720px,某個元素的寬度為 300px,那應該寫成多少 vh 才與 300px 相等呢,如下。
- 300 ÷ (720 ÷ 100) ≈ 41.666
比如設計稿為 1920x1080(單屏設計高度應該更小一點,如適配***節所說),可以寫個 CSS 預處理函數,這樣方便直接使用設計稿的尺寸,以 Sass 為例如下。
- @function vh( $value ) {
- @return ( $value / 1080 / 100 ) + vh;
- }
- 或者
- @function vw( $value ) {
- @return ( $value / 1920 / 100 ) + vw;
- }
然后,300px 可以無縫寫成 vh(300) 或 vw(300)。
so… 對于我們的頁面選擇 vh 一舉兩得,不用寫很多 rem 匹配,也不會出現溢出的問題。
因為高度變矮,內容的尺寸會隨之變小,而頁面是 1190 寬,水平居中布局,所以當只改變瀏覽器寬度的情況下,不會出現寬度變化溢出問題(除非分辨率超大,然后高度居很高,只把寬度縮很小的情況,這個下面會說到)。寫完后在上面列舉的主流分辨率下一一測試通過。
看看效果(當然這個是最終效果,只改變寬度的拉伸適配在***會說):
8、特殊場景
這里就是剛剛說到的 分辨率超大,然后高度居很高,只把寬度縮很小的情況,因為設計稿是長寬比例為橫向矩形,所以明顯與用長寬比為豎向的矩形來看頁面是背道而馳的。
委屈委屈,但還是要兼容下,至少看起來要顯示正常。
8.1、嘗試 rem + vh 方案
一開始想的是 rem + vh 結合使用,根元素 html 使用 vh,其他單位則使用 rem,然后找到有問題的寬高比,通過 @media 方式設置 html 為 vw 來達到適配。
事實是,rem 縮小到一定值就不會再縮小了,這個跟瀏覽器對字體大小限制為最小 12px 一樣,看個例子。
根字體小于 12px 以后,rem 對應的值則都是設置的倍數乘以 12;設置根字體為 vh, vw 單位同理,rem 會在 vh, vw 換算達到 12 以后就不再改變。
PPPS: 是不是有點坑,應該字體的屬性最小值為 12,而其他屬性的值沒有控制才對
所以,如果使用 rem + vh 方案,在界面縮小到一定尺寸后繼續縮小,有些值達到最小值固定不變,而有些值仍在變小,UI 的展示就變得混亂。
8.2、落地方案,vh + vw + JavaScript 計算
而直接在元素的屬性值上設置為 vh 或 vw,所有的值都會實時變動,沒有最小值(除了屬性為字體有最小值),這樣就***程度減少 UI 變亂的情況了,除非縮到很小很小,那就…(此處省略 1000 個字)。
于是乎,現在的想法是
- 在原來以 vh 為基礎的情況下,拷貝所有帶 vh 單位的代碼,把 vh 換成 vw,當然這些改動都在一個比如叫 .vw-mode 的類下面,基本上可以無縫遷移,只需替換 vh 函數名即可。
- 把 .vw-mode 下的內容設置為上下居中。
- 通過 JS 計算,當可視區比例為豎向比例時,則在頂層元素加上 .vw-mode 類名,當比例為橫向比例時,則去掉 .vw-mode 類名。
大致的代碼如下:
CSS
- .homepage.vw-mode {
- font-size: vw(14);
- .com-width {
- width: vw(1190);
- }
- .hp-header {
- padding-top: vw(30);
- // ...更多代碼
- }
- // ...更多代碼
- }
JS
- this.resizeHandler = () => {
- const clientWidth = document.documentElement.clientWidth
- const clientHeight = document.documentElement.clientHeight
- // 當長寬比為豎向比例時
- const isVerticalRatio = clientWidth / clientHeight < 1370 / 890
- $homepageElem.classList[isVerticalRatio ? 'add' : 'remove']('vw-mode')
- }
- this.resizeHandler()
- window.addEventListener('resize', this.resizeHandler)
***的結果就是上面那個 GIF 效果圖了。
9、移動端
移動端用戶是沒法操作瀏覽器的,所以基本上都是標準的長寬比,用 vh 最合適不過了,或 vw。
10、***
體驗(官網):https://ling.jd.com
體驗瀏覽器:Chrome、Safari 新版,其他瀏覽器暫不支持
【本文是51CTO專欄作者“凹凸實驗室”的原創稿件,轉載請通過51CTO聯系原作者獲取授權】