關於一些基本概念如設備像素,css像素,參考javascript
上圖的pt和px互換才正確,reader @2x 指設備像素比css
meta裏面設置width=device-width,這個device-width就是設備獨立像素。html
在chrome裏 看到的375*667是設備獨立像素
前端
設計師給的是640px寬的設計稿是根據設備像素(device pixel,物理像素)爲單位制做的設計稿;而前端工程師參照相關的設備像素比來進行換算,好比根據iPhone5出稿的設計稿的中有一個width:100px,height:200px的按鈕,那麼前端工程師在編碼web頁面時應該寫width:50px,height:100px。他們之間的換算比例是根據設備像素比來計算的。vue
當<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no">
,iphone5的css像素是320X568,當 <meta name="viewport" content="width=device-width, initial-scale=0.5, minimum-scale=0.5, maximum-scale=0.5, user-scalable=no">
,css像素變成640X1136(以下圖),這是由於當scale=1,1個css像素對應2個物理像素,而iphone5的物理像素是640X1136,當scale=0.5,1個css像素對應1個物理像素,css像素必須變成640X1136才能恰好徹底對應全部物理像素,須要注意的是當scale=1,你用css寫div height:50px;在開發者工具inspect div,確實高50px,變成scale=0.5,在開發者工具看div的height仍是50pxjava
rem這個單位表明根元素的 font-size 大小,例如 <html> 元素的font-size爲16px,則1rem=16pxandroid
手機有不少不一樣分辨率,以下圖,若是用響應式,要作3套css,若是隻想作1套css適應不一樣手機,方法是用百分比佈局或總體縮放
git
百分比佈局:
github
缺點是高度不能肯定,不能實現例如寬高2:1,例如.child {height:20%} 是沒用的web
總體縮放:
在解決這個問題上vw是最好的,由於vw和設備寬度有關,1vw=視口寬度的 1/100,但兼容性差
另外的方法就是動態rem,動態rem的簡單實現:https://jsbin.com/zoxizor/1/e...
在 scss 文件裏添加
@function px( $px ){ @return $px/$designWidth*10 + rem; } $designWidth : 640; // 640 是設計稿的寬度, .child{ width: px(320); //5rem height: px(160); margin: px(40) px(40); border: 1px solid red; float: left; font-size: 1.2em; }
便可實現 px 自動變 rem
以 dpr=2 爲例:
你拿到一張標準的基於 iphone6 的設計稿(750px)
你看到它設計的一個 border寬度是 1px
那麼border的實際上是 border: 0.5px solid #000;
但問題是在iOS 7 和以前版本,OS X Mavericks 及之前版本,還有 Android 設備上瀏覽器可能不認識0.5px的邊框,將會把它解釋成0px,沒有邊框。因此網上有不少其餘的實現1px邊框的方法
而所謂的1px變粗請看 javascript - 1px邊框在移動端變粗問題產生的原理 , 移動端高清、多屏適配方案
設計稿上有1像素邊框,當你面對不一樣的屏幕時你但願它的行爲是怎樣的?設計師但願在不一樣dpr的屏幕上這條線都是1物理像素。
下面flexible.js的部分代碼能夠實現,
if (!dpr && !scale) { var isAndroid = win.navigator.appVersion.match(/android/gi); var isIPhone = win.navigator.appVersion.match(/iphone/gi); var devicePixelRatio = win.devicePixelRatio; if (isIPhone) { // iOS下,對於2和3的屏,用2倍的方案,其他的用1倍方案 if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) { dpr = 3; } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){ dpr = 2; } else { dpr = 1; } } else { // 其餘設備下,仍舊使用1倍的方案 dpr = 1; } scale = 1 / dpr; } if (!metaEl) { metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
當直接寫<meta name="viewport" content="initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
,且dpr=2,border:1px,渲染出來是2px物理像素
當<meta name="viewport" content="initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no">
,此時頁面被縮小50%,border:1px渲染出來是1px物理像素
爲了解決1px邊框問題,flexible.js根據dpr對頁面縮放 if (!dpr && !scale) { var isAndroid = win.navigator.appVersion.match(/android/gi); var isIPhone = win.navigator.appVersion.match(/iphone/gi); var devicePixelRatio = win.devicePixelRatio; if (isIPhone) { // iOS下,對於2和3的屏,用2倍的方案,其他的用1倍方案 if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) { dpr = 3; } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){ dpr = 2; } else { dpr = 1; } } else { // 其餘設備下,仍舊使用1倍的方案 dpr = 1; } scale = 1 / dpr; } if (!metaEl) { metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no'); }
致使字體font-size也要作相應調整:
.a{ font-size:12px; } [data-dpr="2"] .a{ font-size: 24px; } [data-dpr="3"] .a{ font-size: 36px; }
設計師本來的要求是這樣的:任何手機屏幕上字體大小都要統一
dpr=2,根據源碼, scale=0.5,因此1個css像素對應1個物理像素,font-size=24px,對應24個物理像素,而dpr=1時font-size=12px,對應12個物理像素,根據下圖,dpr=1的普通屏的1個物理像素寬,物理尺寸上等於dpr=2的retina屏的2個物理像素寬,因此任何手機屏幕上字體的物理尺寸大小同樣
if(document.body.ontouchstart !== undefined){} // 在pc上document.body.ontouchstart是undefined,代表不支持該事件,而在觸屏設備上是null,支持該事件 var x = event.touches[0].clientX //touch點的x座標 // 由於手機支持多點觸控,因此關於touch的信息都放在一個數組裏,touches[0]表示一點觸控,tounch[1]表示另一點觸控 而在pc上用 var x = event.clientX 獲取鼠標點擊的x座標
手機上沒有hover事件,resize事件
更多資料: