雙11上雲86元/年css
原文連接:blog.sjfkai.com/2019/01/29/…html
轉載請註明出處前端
最近剛接觸前端開發,接手了一個移動端H5項目。着實體會掉了前端的坑之多,和H5移動端的坑之多多。git
現在項目告一段落,在這裏作一總結github
介紹方案以前,首先仍是交代一下項目背景與需求,畢竟一切方案也不能脫離實際需求。web
關於自適應方案,google一搜就會有不少結果,可是總的來講我的認爲最有用的仍是手淘的大漠寫的一系列文章,後面會給出原文連接。總的來講主流的方案有rem
和vh
兩種。npm
rem
(font size of the root element)是指相對於根元素的字體大小的單位。簡單的說它就是一個相對單位。看到rem
你們必定會想起em
單位,em
(font size of the element)是指相對於父元素的字體大小的單位。它們之間其實很類似,只不過一個計算的規則是依賴根元素一個是依賴父元素計算。windows
因此簡而言之,就是根據屏幕寬度設置 html
標籤的 font-size
。 再在佈局時使用 rem
單位來佈局,就能夠達到自適應的目的。瀏覽器
使用此方案,能夠藉助手淘的開源項目lib-flexible。它能夠自動幫你設置html
標籤的 font-size
等。將1rem
設置爲屏幕的1/10
。iphone
關於 rem
方案,大漠老師在使用Flexible實現手淘H5頁面的終端適配中進行了詳細的介紹。建議你們閱讀一下。
如你所見,大漠老師也在近期對文正進行了更新,建議你們使用更方便的 vw
方案。
vw
是視口寬度的1/100,用 vw
來作自適應再合適不過了。
好比若是你的設計圖是 750px
的寬度。 對於 75px
的元素就能夠設置爲 10vw
。 這樣在寬度爲 375px
的手機上的表現就是37.5px
。
固然,若是咱們把每一個 px
標註都手動轉換的話,那也是很大的工做量, postcss-px-to-viewport能夠自動幫你轉換爲 vw
。 你只須要在配置時指定設計圖寬度就能夠了。
一樣,強烈建議你去閱讀如下大漠老師關於 vw
佈局的文章 再聊移動端頁面的適配
vw
雖好,惋惜卻沒法知足個人需求。由於 vw
是整個視口寬度的1%,若是單純採用 vw
方案,是沒法限制 body
最大、最小寬度的。
因而我便採用了 vw
+ rem
。 若是屏幕寬度在須要自適應的寬度以內,則將html
標籤的 font-size
設置爲 10vw
。若是屏幕寬度超過最大或最小限制的話。則將html
標籤的 font-size
設置爲固定值。相似於lib-flexible
,將1rem
設爲了 body 寬度的1/10
。
具體 css 以下:
html {
height: 100%;
font-size: 10vw;
}
body {
font-size: 16px;
width: 100%;
height: 100%;
margin: 0 auto;
}
@media screen and (max-width: 320px) {
html{
font-size: 32px;
}
body{
min-width: 320px;
}
}
@media screen and (min-width: 800px) {
html{
font-size: 80px;
}
body{
max-width: 800px;
}
}
複製代碼
固然,這樣在佈局時,咱們就須要使用rem
單位來佈局了。 設計圖標註 px
轉 rem
單位一樣也有現成的工具。博主使用的是postcss-pxtorem。
最終的效果:
以上介紹的適配方案,基本上就能夠知足大部分的需求了。 下面咱們來聊一聊我都遇到了哪些坑。
因爲咱們的方案,全部元素根據屏幕寬度來自適應。於是很難保證轉換後的像素爲整數像素。
在未接觸前端,或者說H5開發以前並無認真考慮太小數像素的問題,最初覺得就是在可現實的精度上四捨五入。真正開發時發現並非這樣的。
好比下面這個例子,一樣的像素值表現就不同:在線實例
IOS
、macOS
設備最小像素好像支持到了0.5px,因此上面的例子在蘋果設備上表現並非很明顯。
可是畢竟大部分設備仍是Android
和windows
系統。
那麼,到底瀏覽器是如何處理小數像素的呢? rem 產生的小數像素問題 這篇文章給出了答案:
瀏覽器在渲染時所作的舍入處理只是應用在元素的渲染尺寸上,其真實佔據的空間依舊是原始大小。
也就是說若是一個元素尺寸是 0.625px,那麼其渲染尺寸應該是 1px,空出的 0.375px 空間由其臨近的元素填充;一樣道理,若是一個元素尺寸是 0.375px,其渲染尺寸就應該是 0,可是其會佔據臨近元素 0.375px 的空間。
複製代碼
那麼在咱們的方案裏會出現什麼問題呢?
border-radius: 50%
畫的圓不圓了對於第一個問題,通常都會出如今標註爲1px
的地方。因此大部分的插件 postcss-pxtorem 或者 postcss-px-to-viewport 都提供了最小轉換像素的選項。 咱們只要指定最小轉換像素,對於比較小的像素(如:1px
),就不轉換爲rem
或vw
了。固然1px
在視網膜屏一樣存在過粗的問題,咱們在以後會討論。
對於剩下的幾個問題,目前本人也沒找到特別好的辦法,畢竟不少地方相差1px
是能夠接受的。只有一些比較小的元素會表現的比較明顯,本人的解決辦法是不經過插件自動轉換爲rem
或vw
,而是經過js
根據設備寬度,計算出該元素在該設備下實際的px
。取整後動態地設置到元素的style
上。這樣就不會出現上述問題了。
若是各位有更好的解決方案的話。歡迎留言討論。
因爲上面小數像素的問題,咱們並無對1px
的元素進行轉換,因此對於750px
的設計圖上1px
的細線,在屏幕寬度爲375px
的iphone6
上依舊爲1px
,按比例應該是0.5px
。因此設計同窗會問:「爲何這條細線變粗了?」 咱們也很無奈啊,由於0.5px
顯不出來啊……
可是轉念一想,對於DPR=2
甚至更高的設備,1px
是由多個物理像素渲染的,實際上是能夠顯示更細的線的。那麼這樣才能畫出更細的線呢?
大漠老師又出場了,《再談Retina下1px的解決方案》中給出了幾種方案:
viewport
放大爲device-width
的dpr
倍數,而後縮小1/dpr
倍顯示border-image
設爲一個一半透明一半顯示的圖片,以達到將邊框一分爲二的目的svg
繪製圖片1px
的邊框,而後縮小1/dpr
倍顯示以上方案各有各的特色,二、3兩個方案畫出來的實際上是0.5px
,而一、4兩個方案畫出來的更接近物理像素的1px
對於添加了 cursor:pointer
屬性的元素,在移動端點擊時,背景會高亮。
爲元素添加 -webkit-tap-highlight-color: transparent;
屬性能夠隱藏背景高亮。
咱們經常使用的垂直居中方式就是使用line-height
,可是這種方法在Android
設備下並不能徹底居中。
具體緣由是由於Android
中文字體排版的問題,能夠參考 知乎:Android瀏覽器下line-height垂直居中爲何會偏離?
經過設置字體,確實可以解決一部分偏離的問題。但仍然會出現一些略微偏離的狀況,聽說與行高奇數偶數有關。不過已經不太容易分辨了,若是仍是不能接受的話建議經過設置上下padding的方式進行垂直居中,再根據具體狀況進行微調。
歡迎關注公衆號 「大前端開發者」。給你帶來更多的前端技術與資訊