2、viewport視口css
瀏覽器可見視口和佈局視口html
- visual viewport:可見視口,即屏幕寬度;
- layout viewport:佈局視口,即DOM寬度;
- idea viewport:理想適口,使佈局視口就是可見視口;
- 設備寬度(visual viewport)與DOM寬度(layout viewport),scale的關係是:
(visual viewport)= (layout viewport)* scale- 獲取屏幕寬度(visual viewport)的尺寸:window. innerWidth/Height
- 獲取DOM寬度(layout viewport)的尺寸:document. documentElement. clientWidth/Height
meta viewport 標籤首先是由蘋果公司在其safari瀏覽器中引入的,目的就是解決移動設備的viewport問題。後來安卓以及各大瀏覽器廠商也都紛紛效仿,引入對meta viewport的支持,事實也證實這個東西仍是很是有用的。前端
在蘋果的規範中,meta viewport 有6個屬性(暫且把content中的那些東西稱爲一個個屬性和值),以下:
width:設置layout viewport 的寬度,爲一個正整數,或字符串"width-device";
initial-scale:設置頁面的初始縮放值,爲一個數字,能夠帶小數;
minimum-scale:容許用戶的最小縮放值,爲一個數字,能夠帶小數;
maximum-scale:容許用戶的最大縮放值,爲一個數字,能夠帶小數;
height:設置layout viewport 的高度,這個屬性對咱們並不重要,不多使用;
user-scalable:是否容許用戶進行縮放,值爲"no"或"yes", no 表明不容許,yes表明容許;android
<meta name="viewport" content="width=device-width,initial-scale=1">
參考:移動前端開發之viewport的深刻理解git
3、物理像素(physical pixel)github
4、CSS像素web
做爲Web開發者,咱們接觸的更多的是用於控制元素樣式的樣式單位像素。這裏的像素咱們稱之爲CSS像素
參考:CSS像素、物理像素、邏輯像素、設備像素比、PPI、Viewport #21
5、設備像素比segmentfault
// 獲取當前設備的dpr: JavaScript: window.devicePixelRatio。 CSS: -webkit-device-pixel-ratio, -webkit-min-device-pixel-ratio, -webkit-max-device-pixel-ratio。不一樣dpr的設備,可根據此作一些樣式適配(這裏只針對webkit內核的瀏覽器和webview)。
6、設備獨立像素dip與設備像素dp瀏覽器
7、屏幕像素密度PPI(pixel per inch)sass
8、概念關係圖
屏幕尺寸、屏幕分辨率-->對角線分辨率/屏幕尺寸-->屏幕像素密度PPI | 設備像素比dpr = 物理像素 / 設備獨立像素dip(dp) | viewport: scale | CSS像素px
CSS像素與設備像素「田字圖解」
9、前端實現相關方式
// 設置理想視口,使得DOM寬度(layout viewport)與屏幕寬度(visual viewport)同樣大,DOM文檔主寬度即爲屏幕寬度,1個CSS像素(1px)由多少設備像素顯示由具體設備而不一樣; <meta name="viewport" content="width=device-width,user-scalable=no,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0">
10、動態設置視口縮放爲1/dpr
(function (doc, win) { var docEl = win.document.documentElement; var resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize'; var metaEl = doc.querySelector('meta[name="viewport"]'); var dpr = 0; var scale = 0; // 對iOS設備進行dpr的判斷,對於Android系列,始終認爲其dpr爲1 if (!dpr && !scale) { var isAndroid = win.navigator.appVersion.match(/android/gi); var isIPhone = win.navigator.appVersion.match(/[iphone|ipad]/gi); var devicePixelRatio = win.devicePixelRatio; if(isIPhone) { dpr = devicePixelRatio; } else { drp = 1; } scale = 1 / dpr; } /** * ================================================ * 設置data-dpr和viewport × ================================================ */ docEl.setAttribute('data-dpr', dpr); // 動態改寫meta:viewport標籤 if (!metaEl) { metaEl = doc.createElement('meta'); metaEl.setAttribute('name', 'viewport'); metaEl.setAttribute('content', 'width=device-width, initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no'); document.documentElement.firstElementChild.appendChild(metaEl); } else { metaEl.setAttribute('content', 'width=device-width, initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no'); } })(document, window);
11、px單位的適配
設置動態縮放視口後,在iphone6上,縮放爲0.5,即CSS像素2px最終顯示效果爲1px,而在scale=1的設備,CSS像素1px顯示效果爲1px,爲了達到顯示效果一致,以px爲單位的元素(好比字體大小),其樣式應有適配不一樣dpr的版本,所以,在動態設置viewport:scale的時候,同時在根元素上加上data-dpr=[dpr],可是這種方式仍是不夠,若是dpr爲2,3以外的其餘數值,px就沒辦法適配到,所以會選擇用rem爲單位進行適配;
.p { font-size: 14px; [data-dpr="2"] & { font-size: 14px * 2; } [data-dpr="3"] & { font-size: 14px * 3; } }
// 爲寫樣式方便,能夠藉助sass的mixin寫代碼片斷: // // 適配dpr的字體大小 @mixin font-dpr($font-size){ font-size: $font-size; [data-dpr="2"] & { font-size: $font-size * 2; } [data-dpr="3"] & { font-size: $font-size * 3; } } @mixin px-dpr($property, $px) { #{$property}: $px; [data-dpr="2"] & { #{$property}: $px * 2; } [data-dpr="3"] & { #{$property}: $px * 3; } } // 使用 @include font-dpr(14px); @include px-dpr(width, 40px); @include px-dpr(height, 40px);
12、設置縮放視口與設置理想視口有什麼不一樣
十3、rem(一個css單位)
設備 | 設備大小 | 根元素font-size/px | 寬度/rem |
---|---|---|---|
iPhone5/SE | 320*568 | js計算所得 | -- |
iPhone6/7/8 | 375*667 | 16 | 23.4375 |
i6/7/8 Plus | 414*736 | js計算所得 | -- |
iPhone x | 375*812 | js計算所得 | -- |
iPad | 768*1024 | js計算所得 | -- |
- | 360 | js計算所得 | -- |
十4、動態設置根元素fontSize
// 以320px的屏幕爲基準 const oHtml = document.getElementsByTagName('html')[0] const width = oHtml.clientWidth; // 320px的屏幕基準像素爲12px oHtml.style.fontSize = 12 * (width / 320) + "px";
/** * 如下這段代碼是用於根據移動端設備的屏幕分辨率計算出合適的根元素的大小 * 當設備寬度爲375(iPhone6)時,根元素font-size=16px; 依次增大; * 限制當爲設備寬度大於768(iPad)以後,font-size再也不繼續增大 * scale 爲meta viewport中的縮放大小 */ (function (doc, win) { var docEl = win.document.documentElement; var resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize'; /** * ================================================ * 設置根元素font-size * 當設備寬度爲375(iPhone6)時,根元素font-size=16px; × ================================================ */ var refreshRem = function () { var clientWidth = win.innerWidth || doc.documentElement.clientWidth || doc.body.clientWidth; console.log(clientWidth) if (!clientWidth) return; var fz; var width = clientWidth; fz = 16 * width / 375; docEl.style.fontSize = fz + 'px'; }; if (!doc.addEventListener) return; win.addEventListener(resizeEvt, refreshRem, false); doc.addEventListener('DOMContentLoaded', refreshRem, false); refreshRem(); })(document, window);
十5、rem計算(px2rem)
/* * 此處 $base-font-size 具體數值根據設計圖尺寸而定 * flexible中設置的標準是【fontSize=16px, when 屏幕寬度=375】,所以,按此標準進行計算, * 若設計圖爲iPhone6(375*667)的二倍稿,則$base-font-size=32px * */ @function px2rem($px, $base-font-size: 32px) { @if (unitless($px)) { @warn "Assuming #{$px} to be in pixels, attempting to convert it into pixels for you"; @return px2rem($px + 0px); // That may fail. } @else if (unit($px) == rem) { @return $px; } @return ($px / $base-font-size) * 1rem; } // 使用,eg: font-size: px2rem(18px);
十6、問題思考
我以前一直在想一個問題,選取哪一個設備來作基準、屏幕寬度等分爲多少比較合適,設計圖給多大寬度的版本?被選取做爲基準的設備,應當就是前端須要設計提供的設計圖版本,這樣能夠避免一些尺寸上的糾纏,而等分爲多少等分,除了考慮方便設計,是否須要考慮其餘問題?對於根元素font-size沒有手動設置的狀況,1rem究竟等於多少?
瞭解到的一些事實:某些Android設備會丟掉 rem 小數部分(具體是哪些設備,搜到的文章中沒有說),那麼1rem對應的px少些,在這些安卓設備上顯示偏差就會較小,固然若是不存在會丟掉小數這個問題,這一說也就沒必要考慮了。
未設置font-size狀況下,1rem的大小具體看瀏覽器的實現,默認的根元素大小是font-size=16px
目前通常會選取iPhone6做爲基準,設計圖便要iPhone6的二倍圖
當動態縮放視口爲1/dpr, 計算所得的根元素fontSize也會跟着縮放,即若理想視口(scale=1), iPhone6根元素fontSize=16px; 若scale=0.5, iPhone6根元素fontSize=32px; 所以設置視口縮放應放於設置根元素fontSize以前;
十7、vm/vh:CSS單位
十8、一些問題
upsampling/downsampling
DownSampling: 大圖放入比圖片尺寸小的容器中時,出現像素分割成就近色
不一樣scale顯示同一圖片基本無問題;同一sacle,不一樣倍數圖,存在色差(Downsampling)
十9、手淘的實現方案
下面主要根據個人理解摘錄了手淘公開的實現方案,詳細能夠去gitHub搜索查看,文末也附了連接。
圖解設計與前端協做方案:圖:手機淘寶團隊適配協做模式
淘寶手淘團隊h5頁面終端適配開源庫:lib-flexible
方案關鍵點:
動態改寫<meta name="viewport">標籤
給<html>元素添加data-dpr屬性,而且動態改寫data-dpr的值
給<html>元素添加font-size屬性,而且動態改寫font-size的值
經過一段JS代碼根據設備的屏幕寬度、dpr設置根元素的data-dpr和font-size, 這段JS代碼要在全部資源加載以前執行,建議作內聯處理。
各類元素(文本、圖片)處理方案參考:
圖:怎樣讓你的網站適應視網膜分辨率
二10、px轉rem的mixin
// 使用sass的混合宏 // 淘寶手淘的方案裏,i6(375pt)屏幕寬度爲10rem,即font-size=75px, scale=0.5 因設計圖爲二倍圖,$base-font-size=75px @mixin px2rem($property,$px-values,$baseline-px:16px,$support-for-ie:false){ //Conver the baseline into rems $baseline-rem: $baseline-px / 1rem * 1; //Print the first line in pixel values @if $support-for-ie { #{$property}: $px-values; } //if there is only one (numeric) value, return the property/value line for it. @if type-of($px-values) == "number"{ #{$property}: $px-values / $baseline-rem; } @else { //Create an empty list that we can dump values into $rem-values:(); @each $value in $px-values{ // If the value is zero or not a number, return it @if $value == 0 or type-of($value) != "number"{ $rem-values: append($rem-values, $value / $baseline-rem); } } // Return the property and its list of converted values #{$property}: $rem-values; } }
二11、小結
二12、Retina視網膜屏
Retina視網膜屏,是指人眼在正常觀察距離(iPhone定義爲10英寸,iPad定義爲15英寸)下,視網膜已經沒法分辨單個像素,再也不出現像素顆粒感,僅能觀察到如絲般細膩的畫面,能夠理解爲超高分辨率屏幕;
最早使用retina屏幕是iphone 4,屏幕分辨率爲960 * 640(326ppi)。
對好比下兩幅圖,能夠清晰地看出是否 Retina 屏的顯示差別:
屏幕快照 2018-08-20 下午3.00.23.png
兩代iPhone 的物理尺寸(屏幕寬高有多少英寸)是同樣的,從上圖能夠看出,iphone 4的顯示效果要明顯好於iphone 3GS,雖然 iPhone 4 分辨率提升了,但它不一樣於普通的電腦顯示器那樣爲了顯示更多的內容,而是提高顯示相同內容時的畫面精細程度。這種提高方式是靠提高單位面積屏幕的像素數量,即像素密度來提高分辨率,這樣作的主要目的是爲了提升屏幕顯示畫面的精細程度。以第三代 MacBook Pro with Retina Display爲例, 工做時顯卡渲染出的2880x1880個像素每四個一組,輸出原來屏幕的一個像素顯示的大小區域內的圖像。這樣一來,用戶所看到的圖標與文字的大小與原來的1440x900分辨率顯示屏相同,但精細度是原來的4倍。
注意:在桌面顯示器中,咱們調整了顯示分辨率,好比從 800 * 600 調整到 1024 * 768 時,屏幕的文字圖標會變小,顯示的內容更多了。但 Retina 顯示方式不會產生這樣的問題,或者說, Retina 顯示技術解決的是顯示畫面精細程度的問題,而不是解決顯示內容容量的問題。
二十3、相關連接
做者:puxiaotaoc 連接:https://www.jianshu.com/p/b13d811a6a76 來源:簡書 著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。