原文鏈接:https://www.cnblogs.com/MaggieGao/p/6994868.html
- 一 怎么書寫可以適用於不同設備的頁面
1 自動適應屏幕寬度 之 viewport --在html中添加meta標簽:網頁的寬度默認等於屏幕的寬度
<meta name="viewport" content="width=device-width, initial-scale=1,user-scalable=0">
擴展viewport屬性:
1>width 設置viewport的寬度,可以是數字,或者使用字符串“device-width”;
2>initial-scale 頁面初始的縮放,首次 load 的時候縮放比例
3>minimum-scale/maximum-scale 允許用戶縮放的最小/最大比例
4>height 設置viewport的高度,很少設置這個屬性
5>user-scalable 用戶是否可以手動縮放 ,一般兩個值 yes/no
特殊說明:老式瀏覽器(IE6,7,8)支持,需要使用除css3mediaqueries.js
<!--[if lt IE 9]> <script src="http://css3-mediaqueries-js.googlecode.com/svn/trunk/css3-mediaqueries.js"></script> <![endif]-->
2 使用框架搭建頁面
1> bootstrap(基於jQuery的響應式工具,適用於移動,pad,pc)
2> ElementUI(PC),MintUI(移動端) 餓了么基於vue組件庫開發的
3 寬度的嚴格布局書寫
因為頁面根據屏幕的寬度調整布局,所以不能使用絕對寬度的布局或者是絕對寬度的元素
一般使用width:50% / width:auto (塊級元素默認是auto)
4 圖片自適應
img {max-width:100%} 由於老的IE不支持max-width{width:100%}
- 二 常見的問題
1 border 1px 問題
由於最小的物理像素差異,一條直線的顯示,iphone5它能顯示的最小寬度其實是理論上說的0.5px。
不是所有手機瀏覽器都能識別border: 0.5px;,ios7以下,android等其他系統里,0.5px會被當成為0px處理
通常是給元素order-bottom: 1px solid #ddd;,然后通過transform: scaleY(.5)縮小0.5倍來達到0.5px的效果,
.scale{ position: relative; } .scale:after{ content:""; position: absolute; bottom:0px; left:0px; right:0px; border-bottom:1px solid #ddd; -webkit-transform:scaleY(.5); -webkit-transform-origin:0 0; }
2 圖片高清問題
通過css媒體查詢庫或者javascript條件判斷,在不同的dpr下加載不同尺寸的圖片
無論從管理上,還是從性能上看,只要有可能,盡量部署獨立的圖片服務器
3 屏幕適配布局問題
響應式布局
流式布局+媒體查詢
用來解決不同寬度的布局問題,父級寬度不夠的時候,子級節點會“擠下去” --- 使用css3,根據屏幕分辨率進行不同的樣式應用
優劣:
這種布局通吃pc和移動端,做到精細處,兩者的效果都很好,
缺點是媒體查詢是有限的,也就是可以枚舉出來的
對設計要求簡單、清晰、復雜的設計稿會直接弄死前端,同時需要多個設計稿
css3低版本瀏覽器不支持
伸縮布局
使用的是Flexbox ,有兼容性問題
整體思路:考慮把一個元素變成一個伸縮容器 -->伸縮容器中子元素的排列方式 -->子元素所占空間
伸縮布局的屬性:
1 主軸方向 flex-direction:row /row-reverse(右到左)/column/column-reverse(下到上)
2 伸縮項目在主軸的對齊方式 justify-content:flex-start /flex-end/center/space-between/space-around
3 伸縮項目是否換行 flex-wrap:nowrap/wrap
4 換行后對齊方式 align-content:stretch:拉伸/flex-start...sapce-around
5 不換行對齊方式 align-items 默認拉伸 值同上
伸縮項目的屬性
1 伸縮項目在伸縮容器中所占的空間 flex 值 數字 比例
2 自己的對齊方式 align -self:start /end/center
3 排列順序 order 數字 值越小越靠前
rem布局
相對單位rem基准值公式:rem=document.documentElement.clientWidth*dpr/10(10是為了取整)
賦值給html的font-size:rem
demo:iPhone4/5 320*2/10=64px
如需改變根節點的html的font-size的rem 屬性可以通過媒體查詢/javascript操作
@media only screen and (min-width: 641px) html { font-size: 125%!important; } @media only screen and (min-width: 561px) html { font-size: 109%!important; } @media only screen and (min-width: 481px) html { font-size: 94%!important; } html { font-size: 62.5%; } http://m.vmall.com/# media (max-width: 414px) html { font-size: 35.9375%; } @media (max-width: 432px) html { font-size: 37.5%; } @media (max-width: 480px) html { font-size: 41.667%; } @media (max-width: 540px) html { font-size: 46.875%; } @media (max-width: 640px) html { font-size: 55.556%; } @media (max-width: 720px) html { font-size: 62.5%; }
JavaScript 方法實現rem var dpr, rem, scale; var docEl = document.documentElement; var fontEl = document.createElement('style'); var metaEl = document.querySelector('meta[name="viewport"]'); scale = 1 / dpr; dpr = win.devicePixelRatio || 1; rem = docEl.clientWidth * dpr / 10; // 設置viewport,進行縮放,達到高清效果 metaEl.setAttribute('content', 'width=' + dpr * docEl.clientWidth + ', initial-scale=' + scale + ',maximum-scale=' + scale + ', minimum-scale=' + scale + ',user-scalable=no'); // 設置data-dpr屬性,留作的css hack之用 docEl.setAttribute('data-dpr', dpr); // 動態寫入樣式 docEl.firstElementChild.appendChild(fontEl); fontEl.innerHTML = 'html{font-size:' + rem + 'px!important;}'; // 給js調用的,某一dpr下rem和px之間的轉換函數 window.rem2px = function(v) { v = parseFloat(v); return v * rem; }; window.px2rem: function(v) { v = parseFloat(v); return v / rem; }; window.dpr = dpr; window.rem = rem;
4 字體大小問題
html上,加入了一個自定義屬性,data-dpr
<html data-dpr='dpr'></html>
處理dpr的值來適配不同屏幕字體
if (!dpr && !scale) { //devicePixelRatio這個屬性是可以獲取到設備的dpr的 var devicePixelRatio = win.devicePixelRatio; //判斷dpr是否為整數 var isRegularDpr = devicePixelRatio.toString().match(/^[1-9]\d*$/g) if (isRegularDpr) { // 對於是整數的dpr,對dpr進行操作 if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) { dpr = 3; } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){ dpr = 2; } else { dpr = 1; } } else { // 對於其他的dpr,人采用dpr為1的方案 dpr = 1; } scale = 1 / dpr; }
如果使用rem會使不同的手機屏幕字體不同,與設計師的需求:手機屏幕的字體大小一致
可以使用less 里的mixin
.px2px(@name, @px){ @{name}: round(@px / 2) * 1px; [data-dpr="2"] & { @{name}: @px * 1px; } // for mx3 [data-dpr="2.5"] & { @{name}: round(@px * 2.5 / 2) * 1px; } // for 小米note [data-dpr="2.75"] & { @{name}: round(@px * 2.75 / 2) * 1px; } [data-dpr="3"] & { @{name}: round(@px / 2 * 3) * 1px } // for 三星note4 [data-dpr="4"] & { @{name}: @px * 2px; } }