from:鏈接
1.Media Queries
meida queries 的方式可以說是最早期的移動端佈局方式,它主要是通過查詢設備的寬度來執行不同的 css 代碼,最終達到界面的配置。核心語法是:
@media screen and (max-width: 600px) { /*當屏幕尺寸小於600px時,應用下面的CSS樣式*/
/*你的css代碼*/
}
優點
- media query可以做到設備像素比的判斷,方法簡單,成本低,特別是對移動和PC維護同一套代碼的時候。目前像Bootstrap等框架使用這種方式佈局
- 圖片便於修改,只需修改css文件
- 調整屏幕寬度的時候不用刷新頁面即可響應式展示
缺點
- 代碼量比較大,維護不方便
- 爲了兼顧大屏幕或高清設備,會造成其他設備資源浪費,特別是加載圖片資源
- 爲了兼顧移動端和PC端各自響應式的展示效果,難免會損失各自特有的交互方式
2.Flex彈性佈局
以天貓的實現方式進行說明:
它的viewport
是固定的:<meta name=“viewport” content=“width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no”>
高度定死,寬度自適應,元素都採用px做單位。
隨着屏幕寬度變化,頁面也會跟着變化,效果就和PC頁面的流體佈局差不多,在哪個寬度需要調整的時候使用響應式佈局調調就行(比如網易新聞),這樣就實現了『適配』。
3.rem + viewport 縮放
這也是淘寶使用的方案,根據屏幕寬度設定 rem 值,需要適配的元素都使用 rem 爲單位,不需要適配的元素還是使用 px 爲單位。(1em = 16px)
PS:rem
rem是CSS3新增的一個相對單位(root em,根em),這個單位引起了廣泛關注。這個單位與em有什麼區別呢?
區別在於使用rem爲元素設定字體大小時,仍然是相對大小,但相對的只是HTML根元素。這個單位可謂集相對大小和絕對
大小的優點於一身,通過它既可以做到只修改根元素就成比例地調整所有字體大小,又可以避免字體大小逐層複合的連鎖
反應。目前,除了IE8及更早版本外,所有瀏覽器均已支持rem。對於不支持它的瀏覽器,應對方法也很簡單,就是多寫一
個絕對單位的聲明。這些瀏覽器會忽略用rem設定的字體大小。比如:p{font-size:14px;font-size:0.875rem;}
(推薦一個單位轉換的工具:http://pxtoem.com/)
實現原理
根據rem將頁面放大dpr倍, 然後viewport設置爲1/dpr.
如iphone6 plus的dpr爲3, 則頁面整體放大3倍, 1px(css單位)在plus下默認爲3px(物理像素)
然後viewport設置爲1/3, 這樣頁面整體縮回原始大小. 從而實現高清。
這樣整個網頁在設備內顯示時的頁面寬度就會等於設備邏輯像素大小,也就是device-width。
這個device-width的計算公式爲:設備的物理分辨率/(devicePixelRatio * scale),
在scale爲1的情況下,device-width = 設備的物理分辨率/devicePixelRatio 。
4、rem實現
比如說“魅族”移動端的實現方式,viewport也是固定的:
<meta name=“viewport” content=“width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no”>
。
通過以下代碼來控制rem基準值(設計稿以720px寬度量取實際尺寸)
以下是控制1rem = 多少px的代碼
//獲取視窗寬度
let htmlWidth = document.documentElement.clientWidth || document.body.clientWidth;
//獲取視窗高度
let htmlDom = document.getElementsByTagName('html')[0];
htmlDom.style.fontSize = htmlWidth / 10 + 'px';
window.addEventListener('resize', (e)=>{
let htmlWidth = document.documentElement.clientWidth || document.body.clientWidth;
htmlDom.style.fontSize = htmlWidth / 10 + 'px';
console.log(htmlDom.style.fontSize)
});
以下是scss
//這裏只是以iphone6作爲基本設計搞,因爲最終得出的單位是rem,而1 rem = 多少px 其實是我們在js代碼中設置的,所以它依舊可以適配其他screen
//當改變屏幕寬度時,1 rem的實際大小被改變,同樣的,實際的顯示效果也會被改變
@function px2rem($px) {
$rem : 37.5px;//不需要因爲屏幕寬度的改變而改變
@return ($px / $rem) + rem;
}
html {
color: #f8f8f8;
}
.header {
height: px2rem(40px);
width: 100%;
background-color: red;
padding-left: px2rem(23px);
box-sizing: border-box;
.header-item {
float: left;
color: #ffcdce;
font-size: px2rem(16px);
margin-right: px2rem(20px);
line-height: px2rem(40px);
&:nth-child(2) {
color: #fff;
font-size: px2rem(16px);
}
}
}