摘要:再談移動端適配百分比解決方案的缺點在我們的項目中大量的使用百分比來解決頁面在寬度上的自適應,其實在高度上并沒有很好的自適應。
前言
這篇文章的內容如題目一樣,主要分為兩個部分,
談談業內主流的移動端適配解決方案
點5像素的由來和實現方法
建議在讀這篇文章的時候先讀下這篇文章《高清屏概念解析與檢測設備像素比的方法_20161005》,因為這些文章涉及的很多概念在這篇文章中都會提到。
1.再談移動端適配 1.1百分比解決方案的缺點在我們的項目中大量的使用百分比來解決頁面在寬度上的自適應,其實在高度上并沒有很好的自適應。所以在我們的前端頁面會出現一些比較奇怪的問題。比如下面這樣:
還有一個比較明顯的問題就是:在任何機型上我們的按鈕的高度是不會變化自適應的,所以小屏手機我們的按鈕看起來很臃腫。
1.2一些常用單位的概念解析在談我為什么在我們的項目中引入rem單位的時候,先來詳細的了解幾個常用的單位概念。
px像素(Pixel)。相對長度單位。像素px是相對于顯示器屏幕分辨率而言的(也就是說是跟物理設備有關的)。拿高清屏和普通屏來做對比就是普通屏幕的1個像素點就是1個物理像素點,而高清屏的1個像素點是4個物理像素點。
em相對長度單位。相對于當前對象內文本的字體尺寸。如當前對行內文本的字體尺寸未被人為設置,則相對于瀏覽器的默認字體尺寸。em單位的特點:1. em的值并不是固定的;2. em會繼承父級元素的字體大小。
rem相對長度單位。rem是CSS3新增的一個相對單位,這個單位引起了廣泛關注。這個單位與em有什么區別呢?區別在于使用rem為元素設定字體大小時,仍然是相對大小,但相對的只是HTML根元素。這個單位可謂集相對大小和絕對大小的優點于一身,通過它既可以做到只修改根元素就成比例地調整所有字體大小,又可以避免字體大小逐層復合的連鎖反應。
任意瀏覽器的默認字體高都是16px。所有未經調整的瀏覽器都符合: 1rem=16px。那么12px=0.75rem,10px=0.625rem。為了簡化font-size的換算,需要在css中的html選擇器中聲明font-size=62.5%,這就使rem值變為 16px*62.5%=10px, 這樣12px=1.2rem, 10px=1rem, 也就是說只需要將原來的px數值除以10,然后換上rem作為單位就行了。
注意:當我們在根節點上設置了font-size基準值以后,在文檔中有使用rem單位的屬性值都是相對于根節點font-size的一個相對值。比如說一些元素的屬性如width height margin等。也正是這個原因,現在很多網站的移動端網站都在使用rem單位作為適配工具。
在使用rem的時候比較麻煩的就是px和rem換算的問題。上面的除10的方案是比較簡單的。但是根據設置基準值的不同換算方法也不一樣。如果我們使用scss來寫我們的樣式表的話,解決方法就比較簡單了,代碼如下:
@function px2rem($px){ @return ($px/10)/2 + rem; // 相當于$px/20 +rem } width:px2rem(100px); //5rem height:px2rem(200px); //10rem1.3為什么引入 rem 單位
由上面的內容已經知道百分比單位在多屏幕適配上的缺點和rem單位的優點。那么rem單位能為我們的開發帶來什么呢?來看一個常見的多列布局,淘寶移動端的商品列表頁,如下圖:
設計稿(不管是iphone6的二倍稿還是iphone5的二倍稿)中給展示商品的坑位的寬高比是固定的。為了能夠使這個列表在不同的屏幕上達到最佳的顯示效果,需要保持寬度和高度比一致。如果使用百分比肯定是滿足不了這個需求的,因為高度上我們沒有辦法控制。
iphone6和iphone5的屏幕寬度和高度比不一樣,當我們使用百分比做多列布局的時候就會出現下面的這種情況:
所以為了滿足商品坑位在不同屏幕上的寬高比一致,淘寶使用的是rem的解決方案,也是目前最好的解決方案。
1.3為什么將計算根元素的font-size值的js放在head標簽中設置根節點font-size值的方法,第一種是使用css的Media queries,示例代碼如下:
@media (min-device-width : 375px) and (max-device-width : 667px) and (-webkit-min-device-pixel-ratio : 2){ html{font-size: 37.5px;} }
上面的這種方式在我之前做過的項目中使用了一段時間。上面的設置方法有一個很明顯的問題font-size是在一個屏幕寬度的區間上有一個基準值。像安卓手機種類的繁多,屏幕大小就更多的情況下,上面的方法很雞肋。
第二種解決方案,就是使用JavaScript根據當前屏幕的寬度動態計算font-size值,這種方法可以保證屏幕寬度連續變化的時候,font-size基準值也是連續變化的。
計算方法可以參考這篇文章《根據iPhone6設計稿動態計算rem值》
那么最后一個問題也來了:為什么將計算rem單位的js放在head標簽里面?
一句話總結:在瀏覽器中文檔流是從上往下加載渲染的。為了保證發生不必要的重繪或者是重排肯定是越早給根節點設置font-size值越好。
1.4什么情況下使用rem來布局和注意的問題整體的布局還是使用百分比
使用rem的最佳場景是,遇到例如多列帶有圖片的列表,常常需要圖片固定寬高比例
研究了一些網站,比如淘寶,對字體字體一般情況建議使用px
出現1px像素線的地方,仍舊使用border-width:1px;而不是border-width:.1rem;
2.點5像素的由來在前言中推薦閱讀的那篇文章中已經知道在 高清屏(Retina) 中控制顯示的最小的物理單元包括4個基本的像素點,而普通屏幕1個點像素就是1個物理像素單元。所以在高清屏(Retina)出來之前,就算我們在css中寫 0.5px,對于顯示屏幕也是不識別的。但是在高清屏(Retina)中我們可以通過間接的方法實現0.5px的效果。
下面的這張圖可能能讓我們迅速回憶上篇文章的內容
來看一段簡單的示例代碼加深理解:
css代碼如下:
.item1{ width:100px; height:50px; border-top:1px solid #000; float: left; margin-top:10px; } .item2{ width:100px; height:50px; margin-top:10px; border-top:.5px solid #de1dfb; float: left; }
chrome中的顯示效果如下圖:
我把這張圖截取下來放到 PS 中放大可以很明顯的看到一些問題。就是高清屏實際上是用了兩排的物理像素點來顯示1px的像素線。且不做特殊處理的話1px和0.5px的在Chrome瀏覽器中顯示效果是相同的。也就是說Chrome瀏覽器不識別0.5px。
但是相同的代碼我在 safari瀏覽器中的效果卻是下面的效果:
下面的效果是我在PS中做了放大后的效果。
所以,我們可以得出一個結論:對于0.5px不同瀏覽器對它的識別是存在差異的。
以下這張圖是一位網友對一些常用設備是否識別0.5px做的統計:
其實從視覺的感受上來說0.5px像素的顯示效果確實是比1px的顯示效果要好很多。大多數情況下也更符合設計稿上的1px線的效果。那么我們有沒有辦法可以讓1px在不同的瀏覽器和設備中顯示真正的1像素的效果呢?
答案是肯定定的。
2.1傳統的實現方法,也就是我們的項目中正在使用的方法:偽元素 + css3的縮放巧妙地實現;
基本步驟就是:
設置目標元素定位參照
給目標元素添加一個偽元素before或者after,并設置絕對定位
給偽元素添上1px的邊框
設置偽元素的寬高為目標元素的2倍
縮小0.5倍(變回目標元素的大小)
使用border-box把border包進來
先來看一個1像素和0.5像素的顯示效果,下面的截圖是在chrome中:
實現的代碼如下:
測試用的邊框測試用的邊框
.item4, .item5 { width: 200px; height: 100px; position: relative; } .item4 { border: 1px solid #000; } .item5::before { content: ""; position: absolute; width: 200%; height: 200%; border: 1px solid #000; transform-origin: 0 0; transform: scale(0.5, 0.5); box-sizing: border-box; }
可以很明顯的看到縮放前和縮放后的效果。在ps中把上面的截圖放大很多倍以后我們可以看到顯示細節。縮放以后確實是使用的最小的物理像素單元來顯示邊框。如下圖:
注意:按照css3 transform 的scale的定義,理論上邊框可以任意細(1/n px)。但是上圖中已經是物理設備能夠使用的最小的物理單元了,那么我們繼續縮放會有什么現象呢?
使用一下代碼
測試用的邊框
.item6::before { content: ""; position: absolute; width: 400%; height: 400%; border: 1px solid #000; transform-origin: 0 0; transform: scale(0.25, 0.25); box-sizing: border-box; }
chrome中顯示效果如下,可以很明顯的看到顏色變淺了,但是是否變得更細了我們肉眼無法分辨:
在PS中放大以后的效果:
很明顯可以看到線并沒有變細,但是線的顏色確實是變淺了。這樣的結果也符合我們的預期,就是已經到了物理設備能夠顯示一塊顏色的最小的物理單元了。
2.2js動態設置viewport的方案一些大廠(所謂的淘寶)的解決方案就是使用js動態獲取屏幕的設備像素比,然后動態設置viewport。當然也是我認為目前最好的解決方案。
meta.setAttribute("content", "initial-scale=" + 1/dpr + ", maximum-scale=" + 1/dpr + ", minimum-scale=" + 1/dpr + ", user-scalable=no");
我們知道,一般我們獲取到的視覺稿大部分是iphone6的,所以我們看到的尺寸一般是雙倍大小的,在使用rem之前,我們一般會自覺的將標注/2,其實這也并無道理,但是當我們配合rem使用時,完全可以按照視覺稿上的尺寸來設置。
設計給的稿子雙倍的原因是iphone6這種屏幕屬于高清屏,也即是設備像素比(device pixel ratio)dpr比較大,所以顯示的像素較為清晰。
一般手機的dpr是1,iphone4,iphone5這種高清屏是2,iphone6s plus這種高清屏是3,可以通過js的window.devicePixelRatio獲取到當前設備的dpr,所以iphone6給的視覺稿大小是(*2)750×1334了。
拿到了dpr之后,我們就可以在viewport meta頭里,取消讓瀏覽器自動縮放頁面,而自己去設置viewport的content例如(這里之所以要設置viewport是因為我們要實現border1px的效果,在scale的影響下,高清屏中就會顯示成0.5px的效果)
總結:由以上兩個部分的內容可以知道,不管是在做多終端適配還是實現點5像素的線,都是存在css和js兩種解決方案的。兩種方案相比來說,我都認為使用JavaScript的解決方案都勝一籌。唯一的缺點就是會在html的head標簽中引入一段js代碼 。
記得剛入行的時候,業內有一個叫“雅虎軍規”的東西,是好多前端做頁面優化參考的標準。其中有一條就是要將js文件放在body標簽的底部。到現在很多年了,時代在變化,我們的網絡帶寬也在提升,“雅虎軍規”中的一些內容,可能有些已經不適合我們現在應用開發的場景。而且我覺的做技術不應該拘泥于已有的一些規定,而應該按照我們的場景選擇適合我們的技術和解決方案。
縱然有瑕疵,有些也是可以通過技術手段來解決的。比如在head標簽中引入計算font-size和檢測設備獨立像素比的js的時候,會擔心js的執行阻塞頁面的渲染。而我們完全可以通過review的方式確定js代碼的執行不會出現阻塞,而影響文檔流的加載。
還是那句話:沒有十全十美的技術方案,只有適合不合適當前業務場景的技術方案。。
參考文章[css3的字體大小單位[rem]到低好在哪里](https://www.zhihu.com/questio...
移動端高清、多屏適配方案
使用Flexible實現手淘H5頁面的終端適配
lib-flexible源代碼
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/80622.html
摘要:不要再問我的問題系列一不要再問我的指向問題了二不要再問我跨域的問題了移動端適配的問題,一般來說我們都不會去深究,因為這種東西都是配置一次就再也不用管的了,接到設計圖就按照祖傳套路擼就完事了。 不要再問我XX的問題系列:一、不要再問我this的指向問題了二、不要再問我跨域的問題了 移動端適配的問題,一般來說我們都不會去深究,因為這種東西都是配置一次就再也不用管的了,接到設計圖就按照祖傳...
摘要:不要再問我的問題系列一不要再問我的指向問題了二不要再問我跨域的問題了移動端適配的問題,一般來說我們都不會去深究,因為這種東西都是配置一次就再也不用管的了,接到設計圖就按照祖傳套路擼就完事了。 不要再問我XX的問題系列:一、不要再問我this的指向問題了二、不要再問我跨域的問題了 移動端適配的問題,一般來說我們都不會去深究,因為這種東西都是配置一次就再也不用管的了,接到設計圖就按照祖傳...
摘要:不要再問我的問題系列一不要再問我的指向問題了二不要再問我跨域的問題了移動端適配的問題,一般來說我們都不會去深究,因為這種東西都是配置一次就再也不用管的了,接到設計圖就按照祖傳套路擼就完事了。 不要再問我XX的問題系列:一、不要再問我this的指向問題了二、不要再問我跨域的問題了 移動端適配的問題,一般來說我們都不會去深究,因為這種東西都是配置一次就再也不用管的了,接到設計圖就按照祖傳...
閱讀 3358·2021-09-30 09:47
閱讀 2742·2021-08-18 10:22
閱讀 2527·2021-08-16 10:49
閱讀 2893·2019-08-30 15:53
閱讀 2737·2019-08-29 16:14
閱讀 3190·2019-08-28 18:18
閱讀 3236·2019-08-26 13:21
閱讀 794·2019-08-26 12:02