前端適配方案

在進(jìn)入正文之前,我們需要先了解一些viewport相關(guān)的概念。

viewport

一般來說竹揍,我們?cè)诖a的最開始會(huì)寫上這么一句

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">

移動(dòng)端瀏覽器可以在一個(gè)比屏幕更寬的虛擬”窗口“中渲染頁面,從而無需將所有頁面都?jí)嚎s進(jìn)小屏幕里(那樣會(huì)把很多沒有針對(duì)移動(dòng)端進(jìn)行優(yōu)化的站點(diǎn)打亂)。用戶可以通過平移和縮放來瀏覽頁面的不同區(qū)域径簿。比如我們把一個(gè)頁面的寬度寫成了10000px,那么我們照樣可以通過平移縮放來看到這個(gè)頁面嘀韧,當(dāng)然這是不可取的篇亭,所以我們就需要以上代碼,將viewport的width設(shè)置為設(shè)備的寬度锄贷,縮放的倍數(shù)是1译蒂,且不讓用戶進(jìn)行縮放(這個(gè)可以根據(jù)實(shí)際業(yè)務(wù)場(chǎng)景來設(shè)置)曼月。經(jīng)過以上設(shè)置,我們就可以開始進(jìn)入愉快寫代碼的第一步了~

  • 物理像素DP(device pixels)和css像素

物理像素一般在設(shè)備出廠的時(shí)候就被設(shè)置好了柔昼,也叫設(shè)備像素哑芹,單 位是pt(point)pt是一個(gè)物理單位捕透,指的是組成顯示器屏幕的絕對(duì)長度聪姿。我們買電視機(jī)的時(shí)候,會(huì)說乙嘀,我買個(gè)70寸的電視機(jī)末购。

1英寸=72pt

px(pixel)是一個(gè)虛擬的單位,也是一個(gè)相對(duì)的單位乒躺。根據(jù)《CSS權(quán)威指南》的像素理論中的解釋:

顯示器上的小色框是像素
CSS2.1 建議采用96ppi(pixels per inch)招盲,這是Windows機(jī)器常用的度量。Mac系統(tǒng)下用的是72ppi嘉冒。

摘錄來自: Eric Meyer. “CSS權(quán)威指南第三版”曹货。 iBooks.

1px=1/ppi英寸

通過inch就可以連接器pt和px的關(guān)系。


mac網(wǎng)頁的例子
  • 設(shè)備獨(dú)立像素DIP(Device independent Pixel)

設(shè)備獨(dú)立像素讳推,也稱為邏輯像素顶籽,也叫css像素。我們可以通過screen.width或者screen.height輸出银觅。比如iPhone的css像素就是375px*667px礼饱,iPhone 6 則采用了750×1334分辨率的屏幕,PPI值為326究驴。

iphone6示例圖

物理像素和css像素的計(jì)算公式是:

DPR = 物理像素/CSS像素

css reset樣式重置

為什么要進(jìn)行css reset操作镊绪?

css reset主要是因?yàn)閔tml標(biāo)簽在瀏覽器中都有各自的默認(rèn)樣式。

比如: p 標(biāo)簽有上下邊距洒忧,strong標(biāo)簽有字體加粗樣式蝴韭,em標(biāo)簽有字體傾斜樣式。不同瀏覽器的默認(rèn)樣式之間也會(huì)有差別熙侍,例如ul默認(rèn)帶有縮進(jìn)的樣式榄鉴,在IE 下,它的縮進(jìn)是通過margin實(shí)現(xiàn)的蛉抓,而Firefox下庆尘,它的縮進(jìn)是由padding實(shí)現(xiàn)的。在切換頁面的時(shí)候巷送,瀏覽器的默認(rèn)樣式往往會(huì)給我們帶來麻煩驶忌,影響開發(fā)效率。所以解決的方法就是一開始就將瀏覽器的默認(rèn)樣式全部去掉惩系,更準(zhǔn)確說就是通過重新定義標(biāo)簽樣式位岔。

常用的適配方案

  • flex
<div class="content">
     <div class="con">
         <div class="a"></div>
     </div>
     <div class="con">
         <div class="a"></div>
     </div>
     <div class="con">
         <div class="a"></div>
     </div>
</div>

    .content{
         display: flex;
    }
    .con{
         display: flex;
         justify-content:center;
         align-items:center;
         flex:1;
         height: 300px;
         background: #999;
         color:#fff;
         border:1px solid #000;
    }
    .a{
         width: 30px;
         height: 30px;
         background: #f00;
    }
demo

demo地址

  • 媒體查詢media query

    一個(gè)媒體查詢由一個(gè)可選的媒體類型和零個(gè)或多個(gè)使用媒體功能的限制了樣式表范圍的表達(dá)式組成如筛,例如寬度、高度和顏色抒抬。媒體查詢杨刨,添加自CSS3,允許內(nèi)容的呈現(xiàn)針對(duì)一個(gè)特定范圍的輸出設(shè)備而進(jìn)行裁剪擦剑,而不必改變內(nèi)容本身妖胀。

    我們把上面flex的css換掉其中a的樣式,來看一下media query的作用惠勒。

    .a{
     background:#f00;
    }
    @media (max-width: 800px) {
     .a {
     width:50px;
     height:50px;
     font-size:12px;
     color:#2e9900;
     }
    }
    @media (min-width:801px) and (max-width:1000px) {
     .a {
     width:200px;
     height:200px;
     font-size:20px;
     color:blue;
     }
    }
    @media (min-width: 1001px) {
     .a {
     width:450px;
     height:450px;
     font-size:40px;
     }
    }

media query demo

  • transform-scale

其實(shí)我自己覺得transform-scale是一個(gè)不錯(cuò)的適配方式赚抡,簡單明了,而且暫時(shí)也沒有遇到過什么適配方面的大坑纠屋,相對(duì)而言還比較精確涂臣。

處理方式很簡單,樣式完全按照設(shè)計(jì)稿的px來寫售担。然后在js中計(jì)算當(dāng)前頁面的寬度與設(shè)計(jì)稿的寬度的比赁遗,直接對(duì)body進(jìn)行transform-scale的縮放。

如果非要說有什么問題的話族铆,那就是如果需要考慮橫屏受眾岩四,那就得針對(duì)一些橫屏的狀態(tài)做一些特殊處理。還有就是transform-scale縮小沒有問題哥攘,放大的話剖煌,會(huì)導(dǎo)致頁面模糊。

這個(gè)方案就看自己業(yè)務(wù)需求來選擇了逝淹。

  • rem

rem算是一個(gè)使用很廣泛的適配方案了耕姊。

實(shí)現(xiàn)的方式就是給html根節(jié)點(diǎn)設(shè)置一個(gè)font-size,作為頁面計(jì)算的基準(zhǔn)栅葡。一般這個(gè)基準(zhǔn)會(huì)根據(jù)設(shè)計(jì)稿來定箩做。

假設(shè)設(shè)計(jì)稿的寬度是750px,那最初我們可以將font-size設(shè)為75px妥畏,頁面寬度就是10rem。

然后在頁面中用js動(dòng)態(tài)獲取一下當(dāng)前頁面寬度安吁,計(jì)算出頁面寬度與750px的比例醉蚁,獲取當(dāng)前頁面根節(jié)點(diǎn)上應(yīng)該帶上多大的font-size,假設(shè)當(dāng)前頁面寬度是375px鬼店,那么根節(jié)點(diǎn)上帶上的font-size應(yīng)該是37.5px网棍。

這個(gè)方案是一個(gè)與dpr無關(guān)的方案,就是說完全依賴的是設(shè)備獨(dú)立像素而不是設(shè)備的物理像素妇智,這樣就會(huì)存在一個(gè)問題滥玷,在dpr較大的高清屏上氏身,可能導(dǎo)致模糊。

當(dāng)然惑畴,我們也是可以加上dpr來計(jì)算根節(jié)點(diǎn)的font-size的蛋欣。

  • flexible.js

flexible是手淘的一套解決方案,這是一套dpr相關(guān)的解決方案如贷。

實(shí)現(xiàn)的原理是:

flexible將頁面分成100份陷虎,即100a,10a=1rem杠袱。比如尚猿,頁面寬度為750px,那么一份為75px,1rem=75px。

通過js動(dòng)態(tài)獲取當(dāng)前頁面的dpr和設(shè)備獨(dú)立像素徙鱼。拿iPhone 8 plus舉例南窗,得到dpr是3,設(shè)備獨(dú)立像素是414px舷蒲。那么html上寫的font-size的大小是這么計(jì)算的:

dpr * 414 / 10

最終得到的font-size值是124.2px,然后在meta的initial-scale里會(huì)根據(jù)dpr再進(jìn)行一下頁面縮放,這就可以保證頁面的精細(xì)程度惨恭。

但是如果在meta viewport中手動(dòng)設(shè)置了initial-scale,那么不管js獲取到的dpr是多少耙旦,都會(huì)強(qiáng)制認(rèn)為dpr是手動(dòng)設(shè)置的值脱羡;

手淘處理文字的方式,并沒有采用rem免都,因?yàn)閞em計(jì)算出的小數(shù)锉罐,在對(duì)小數(shù)敏感度不一樣的機(jī)型上會(huì)導(dǎo)致展示誤差,且小于12px的文字并不會(huì)正常被渲染绕娘。也會(huì)導(dǎo)致一些line-height的問題脓规。

  • vm

隨著前端技術(shù)的演進(jìn),vw這個(gè)單位又走上了歷史的舞臺(tái)险领。

CSS Values and Units Module Level 3中和Viewport相關(guān)的單位有四個(gè)侨舆,分別為vwvh绢陌、vminvmax挨下。

-   `vw`:是Viewport's width的簡寫,`1vw`等于`window.innerWidth`的`1%`

-   `vh`:和`vw`類似,是Viewport's height的簡寫脐湾,`1vh`等于`window.innerHeihgt`的`1%`

-   `vmin`:`vmin`的值是當(dāng)前`vw`和`vh`中較小的值

-   `vmax`:`vmax`的值是當(dāng)前`vw`和`vh`中較大的值

常見的屏幕適配問題和解決方案

  • line-height
    一般客戶端的webview會(huì)有一個(gè)默認(rèn)的line-height臭笆,大概會(huì)是在22px的樣子。我們有可能會(huì)遇到一個(gè)問題就是,在我們?cè)O(shè)置好一個(gè)line-height之后愁铺,但是渲染出來的文字相對(duì)于我們預(yù)想的是偏上的鹰霍。導(dǎo)致這個(gè)問題的原因是,我們?cè)O(shè)置的line-height是小于webview預(yù)設(shè)的最小line-height的茵乱,這樣我們?cè)O(shè)置的那個(gè)值會(huì)被忽略茂洒。
    解決的方案是:
    盡量保證font-size是大于12px的,將line-height設(shè)置為1似将,使用上下padding使文字居中获黔。在一些必須需要font-size小于12px的地方,可以先放font-size大于12px在验,再用transform:scale去縮小玷氏。
    但是這一點(diǎn)從實(shí)際經(jīng)驗(yàn)來看,我更偏愛手淘的方案腋舌,根據(jù)dpr或者mediaquery設(shè)置一個(gè)固定的字體盏触,這就需要和設(shè)計(jì)同學(xué)定下一個(gè)設(shè)計(jì)規(guī)范。
  • 中英文的字號(hào)一樣块饺,但是實(shí)際高度卻不一樣
    文字的大小赞辩,取決于設(shè)計(jì)文字的人,就像我們前幾天遇到的英文比中文同字號(hào)小的問題授艰,如果光靠上下的padding來寫的話辨嗽,那就可能會(huì)出現(xiàn)純英文或者數(shù)字那塊會(huì)比較矮。
  • 1像素問題
    產(chǎn)生原因:因?yàn)閐pr高的設(shè)備下淮腾,寫的1像素糟需,實(shí)際是比1的dpr倍。
    解決方案:1)如果整體縮放頁面的話谷朝,1像素的線也會(huì)被一起縮放
    2)可以將線條所在元素用transform-scale縮小
  • 如果設(shè)計(jì)師在設(shè)計(jì)稿上使用的文字很細(xì)洲押,比如華文細(xì)黑這樣的,那前端為了適配更完美圆凰,可以用一個(gè)樣式-webkit-font-smoothing: antialiased;
  • 在移動(dòng)端我們寫了overflow:scroll;之后杈帐,滑動(dòng)可能并不能像我們預(yù)料中的那么順暢,可以使用樣式-webkit-overflow-scrolling: touch;
  • 如果input或button的有怪異的默認(rèn)樣式,嘗試appearance:none;(-webkit-appearance:none;)

參考文檔:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市回怜,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖玉雾,帶你破解...
    沈念sama閱讀 212,383評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件翔试,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡复旬,警方通過查閱死者的電腦和手機(jī)垦缅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來驹碍,“玉大人壁涎,你說我怎么就攤上這事≈就海” “怎么了怔球?”我有些...
    開封第一講書人閱讀 157,852評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長浮还。 經(jīng)常有香客問我竟坛,道長,這世上最難降的妖魔是什么钧舌? 我笑而不...
    開封第一講書人閱讀 56,621評(píng)論 1 284
  • 正文 為了忘掉前任担汤,我火速辦了婚禮,結(jié)果婚禮上洼冻,老公的妹妹穿的比我還像新娘崭歧。我一直安慰自己,他們只是感情好撞牢,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評(píng)論 6 386
  • 文/花漫 我一把揭開白布率碾。 她就那樣靜靜地躺著,像睡著了一般普泡。 火紅的嫁衣襯著肌膚如雪播掷。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,929評(píng)論 1 290
  • 那天撼班,我揣著相機(jī)與錄音歧匈,去河邊找鬼。 笑死砰嘁,一個(gè)胖子當(dāng)著我的面吹牛件炉,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播矮湘,決...
    沈念sama閱讀 39,076評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼斟冕,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了缅阳?” 一聲冷哼從身側(cè)響起磕蛇,我...
    開封第一講書人閱讀 37,803評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后秀撇,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體超棺,經(jīng)...
    沈念sama閱讀 44,265評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評(píng)論 2 327
  • 正文 我和宋清朗相戀三年呵燕,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了棠绘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,716評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡再扭,死狀恐怖氧苍,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情泛范,我是刑警寧澤让虐,帶...
    沈念sama閱讀 34,395評(píng)論 4 333
  • 正文 年R本政府宣布,位于F島的核電站敦跌,受9級(jí)特大地震影響澄干,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜柠傍,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評(píng)論 3 316
  • 文/蒙蒙 一麸俘、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧惧笛,春花似錦从媚、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至各谚,卻和暖如春紧憾,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背昌渤。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評(píng)論 1 266
  • 我被黑心中介騙來泰國打工赴穗, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人膀息。 一個(gè)月前我還...
    沈念sama閱讀 46,488評(píng)論 2 361
  • 正文 我出身青樓般眉,卻偏偏與公主長得像,于是被迫代替她去往敵國和親潜支。 傳聞我的和親對(duì)象是個(gè)殘疾皇子甸赃,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評(píng)論 2 350