就目前看來,web的屏幕適配是貫穿整個前端行業的,如常見的PC端,移動端,響應式,小程序等。javascript
PC端的屏幕具有如下特色:css
13.3英寸
正是由於 PC端上的瀏覽器大小會常常被改變,並且改變的範圍還很大,用戶會全屏瀏覽器,用戶也會縮小瀏覽器到一個很小的值,如600px左右。 因此pc端上若是使用流式佈局(百分比佈局),會致使頁面很難看。html
因此,PC端上只能經過版心佈局來解決這種狀況。前端
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>版心佈局</title>
<style> * { margin: 0; padding: 0; box-sizing: border-box; } html,body{ height: 100%; background-color: #ccc; } main{ width: 1200px; height: 100%; margin: 0 auto; font-size: 40px; background-color: pink; } header{ height: 80px; background-color: aqua; } </style>
</head>
<body>
<main>
<header>版心</header>
<section>內容</section>
</main>
</body>
</html>
複製代碼
移動端下的屏幕存在如下特色:java
移動端因爲屏幕總體比PC端小,並且也不能出現拖動瀏覽器來調整大小的狀況,因此在移動端上的佈局是流式佈局最多,其中有些小分支,如固定小版心。css3
流式佈局,也叫作百分比佈局,指的是頁面上大部分的容器和元素的寬度都不是定死,多是 百分比單位,也多是rem單位nginx
普通的圖片和容器,寫單位的時候換成 百分比 或者 flex便可。git
對於頁面中的某些元素,如字體大小,可使用 淘寶 flexibile + rem
的解決方案github
淘寶flexibleweb
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>流式</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no">
<style> * { margin: 0; padding: 0; box-sizing: border-box; } body { background-color: #ccc; } ul { list-style: none; display: flex; height: 100px; } li { flex: 1; border: 1px solid #000; background-color: aqua; } </style>
</head>
<body>
<main>
<section>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</section>
</main>
</body>
</html>
複製代碼
flexible 和flex佈局不要緊 老婆和老婆餅 也沒有關係
這個解決方案是能夠和以上的流式佈局搭配使用的,rem的做用是主要是針對字體實現 跟隨屏幕變化而變化
rem css單位,相對長度,它的值等於根標籤的字體大小如
<style> html { font-size: 100px; } div { /* 相對於 100px */ font-size: 1rem; } </style>
<div>
rem單位
</div>
複製代碼
效果
淘寶flexible
流程
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>版心佈局</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no">
<script> (function flexible(window, document) { var docEl = document.documentElement; var dpr = window.devicePixelRatio || 1; function setBodyFontSize() { if (document.body) { document.body.style.fontSize = 12 * dpr + "px"; } else { document.addEventListener("DOMContentLoaded", setBodyFontSize); } } setBodyFontSize(); function setRemUnit() { var rem = docEl.clientWidth / 10; docEl.style.fontSize = rem + "px"; } setRemUnit(); window.addEventListener("resize", setRemUnit); window.addEventListener("pageshow", function (e) { if (e.persisted) { setRemUnit(); } }); if (dpr >= 2) { var fakeBody = document.createElement("body"); var testElement = document.createElement("div"); testElement.style.border = ".5px solid transparent"; fakeBody.appendChild(testElement); docEl.appendChild(fakeBody); if (testElement.offsetHeight === 1) { docEl.classList.add("hairlines"); } docEl.removeChild(fakeBody); } })(window, document); </script>
<style> * { margin: 0; padding: 0; box-sizing: border-box; } </style>
</head>
<body>
<div>
</div>
<script> window.onload = function () { setFont(); window.addEventListener("resize", function () { setFont(); }) function setFont() { var div = document.querySelector("div"); div.style.fontSize = document.querySelector("html").style.fontSize; div.innerHTML = "html的字體大小爲" + document.querySelector("html").style.fontSize; } } </script>
</body>
</html>
複製代碼
根據以上的特色
flexible
把 根標籤字體大小改成 屏幕的十分之一rem
能夠根據根標籤的字體大小改變而發生改變得出如下解決方案
假定設計稿的寬度 是 640px
根標籤的字體大小爲 64px
也就是 1 rem = 64px
=> 1px=1/64rem
原設計稿中的div大小爲100px,字體大小爲100px
將px單位修改成 rem單位
div{
width:100px;
font-size:100px;
}
修改成
div{
width:calc( 100rem / 64 );
font-size:calc( 100rem / 64 );
}
複製代碼
將設計稿的寬度也抽象出去
div{
width:calc( 100rem / 十分之一的設計稿寬度 );
font-size:calc( 100rem / 十分之一的設計稿寬度 );
}
複製代碼
完整代碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>版心佈局</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no">
<script> (function flexible(window, document) { var docEl = document.documentElement; var dpr = window.devicePixelRatio || 1; function setBodyFontSize() { if (document.body) { document.body.style.fontSize = 12 * dpr + "px"; } else { document.addEventListener("DOMContentLoaded", setBodyFontSize); } } setBodyFontSize(); function setRemUnit() { var rem = docEl.clientWidth / 10; docEl.style.fontSize = rem + "px"; } setRemUnit(); window.addEventListener("resize", setRemUnit); window.addEventListener("pageshow", function (e) { if (e.persisted) { setRemUnit(); } }); if (dpr >= 2) { var fakeBody = document.createElement("body"); var testElement = document.createElement("div"); testElement.style.border = ".5px solid transparent"; fakeBody.appendChild(testElement); docEl.appendChild(fakeBody); if (testElement.offsetHeight === 1) { docEl.classList.add("hairlines"); } docEl.removeChild(fakeBody); } })(window, document); </script>
<style> * { margin: 0; padding: 0; box-sizing: border-box; } div { width: calc(100rem / 64); height: calc(100rem / 64); font-size: calc(100rem / 64); background-color: aqua; } </style>
</head>
<body>
<div>
</div>
<script> window.onload = function () { setFont(); window.addEventListener("resize", function () { setFont(); }) function setFont() { var div = document.querySelector("div"); div.style.fontSize = document.querySelector("html").style.fontSize; div.innerHTML = "html的字體大小爲" + document.querySelector("html").style.fontSize; } } </script>
</body>
</html>
複製代碼
最終效果
小板心的作法其實也是流式佈局中的一種,只不過對最外層容器加了一個最大寬度的設置如
main{
max-width:540px;
}
複製代碼
小程序端能夠理解特殊的移動端,只不太小程序端不存在 rem
這個單位,取而代之的是 rpx
這個單位,翻譯就是響應式像素,功能相似 rem
小程序中不須要引入淘寶flexible
這個庫,由於內置的 rpx
單位就是實現了 rem + fleixible
功能。
小程序中,存在 屏幕的寬度 統一爲 750 rpx
所以:存在如下關係。
屏幕寬度 | 換算關係 px 和 rpx |
---|---|
750 px | 1 px = 1 rpx |
375 px | 1px = 2 rpx |
any px | 1 px = any / 750 rpx |
如 設計稿爲 375px,其中存在一個view
寬度高度均爲 100px ,字體大小 爲 100px
view {
width: 200rpx;
height: 200rpx;
font-size: 200rpx;
background-color: aqua;
}
<view> 小程序rpx </view>
複製代碼
在移動端中,還存在如下單位,也很好用,能夠很方便解決問題。
單位 | 名稱 |
---|---|
vw | 100vw 等於 視口的寬度 |
vh | 100vh 等於 視口的高度 |
vMax | vw 和 vh 中的較大的那個 |
vMin | vw 和 vh 中的較小的那個 |
以上單位 在移動端中,或者在小程序中都支持。
設計稿爲 375px
,存在一個大小爲100px
的div
,字體大小也爲100px
。
375px = 100 vw
那麼 1 px = 100vw / 375
100px = 100vw * 100 / 375
;注意 calc的語法比較嚴格 尤爲注意空格
main {
background-color: pink;
width: calc(100vw * 100 / 375);
height: calc(100vw * 100 / 375);
font-size: calc(100vw * 100 / 375);
}
複製代碼
響應式的概念分爲兩大類
後臺服務器根據前端瀏覽器的User-Agent
來判斷來源請求是PC端仍是移動端,而後服務器動態返回PC端頁面或者移動端頁面。nginx中很容易就出現該功能。京東,天貓,淘寶也是這樣子的。
主要是指經過媒體查詢來實現。
前端寫好一套代碼 html + css + javascript
,就能夠冬天的根據屏幕的寬度來改變頁面的樣式
這種作法體驗不是最好,可是倒是最小的代碼實現了 兼容pc端和移動端。通常是對頁面要求不高或者小企業使用。
因爲還要兼容到pc端,因此通常作響應式頁面 不會用過高級的h5 css3 的技術。
如 實現一個 大屏幕下 一行顯示3列,小屏幕下 一行顯示2列。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style> * { margin: 0; padding: 0; box-sizing: border-box; } ul { overflow: hidden; } li { float: left; height: 100px; border: 1px solid #000; background-color: pink; } /* 大屏幕 */ @media screen and (min-width:800px) { li { width: 33.33%; } } /* 小屏幕 */ @media screen and (max-width:800px) { li { width: 50%; background-color: lawngreen; } } </style>
</head>
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
</ul>
</body>
</html>
複製代碼
業內要實現響應式佈局時,通常會使用 推特公司的 bootstrap 框架,好評度很高,並且還針對ie8 作了兼容處理。