淺談-web屏幕適配的解決方案

淺談-web屏幕適配的解決方案

img

就目前看來,web的屏幕適配是貫穿整個前端行業的,如常見的PC端,移動端,響應式,小程序等。javascript

1562402019217

PC端

特色

PC端的屏幕具有如下特色:css

  1. 屏幕大小通常是大於 13.3英寸
  2. 用戶會常常拖拉瀏覽器的大小

1562399024495

緣由

正是由於 PC端上的瀏覽器大小會常常被改變,並且改變的範圍還很大,用戶會全屏瀏覽器,用戶也會縮小瀏覽器到一個很小的值,如600px左右。 因此pc端上若是使用流式佈局(百分比佈局),會致使頁面很難看。html

img

解決

因此,PC端上只能經過版心佈局來解決這種狀況。前端

  • 當屏幕大於版心寬度時,版心居中顯示
  • 當屏幕小於版心寬度時,屏幕出現一個橫向的滾動條,這種方案几乎全部的PC端網站都在採用。

案例

img

代碼

<!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>
複製代碼

效果

1562400533725

移動端

特色

移動端下的屏幕存在如下特色:java

  • 屏幕相比較於PC端要小
  • 瀏覽器不PC端,隨時各類調整大小

緣由

移動端因爲屏幕總體比PC端小,並且也不能出現拖動瀏覽器來調整大小的狀況,因此在移動端上的佈局是流式佈局最多,其中有些小分支,如固定小版心。css3

解決

流式佈局,也叫作百分比佈局,指的是頁面上大部分的容器和元素的寬度都不是定死,多是 百分比單位,也多是rem單位nginx

案例

2019-04-30090218

代碼

普通的圖片和容器,寫單位的時候換成 百分比 或者 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>
複製代碼

效果

2019-04-30090218

淘寶flexible + rem

flexible 和flex佈局不要緊 老婆和老婆餅 也沒有關係

這個解決方案是能夠和以上的流式佈局搭配使用的,rem的做用是主要是針對字體實現 跟隨屏幕變化而變化

  1. rem css單位,相對長度,它的值等於根標籤的字體大小如

    <style> html { font-size: 100px; } div { /* 相對於 100px */ font-size: 1rem; } </style>
      <div>
        rem單位
      </div>
    複製代碼

    效果

    1562403035527

  2. 淘寶flexible

    1. 是手淘團隊出的一個處理移動端rem設置的js庫
    2. 把根標籤的字體大小改爲了 當前屏幕的十分之一大小
    3. 根標籤的字體大小發生改變了,使用了rem單位的元素或者字體大小也跟着改變

流程

1562486744388

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效果

2019-04-30090218

綜合flexible 和 rem

根據以上的特色

  • flexible根標籤字體大小改成 屏幕的十分之一
  • rem 能夠根據根標籤的字體大小改變而發生改變

得出如下解決方案

  1. 假定設計稿的寬度 是 640px

  2. 根標籤的字體大小爲 64px 也就是 1 rem = 64px => 1px=1/64rem

  3. 原設計稿中的div大小爲100px,字體大小爲100px

  4. 將px單位修改成 rem單位

    div{
    	width:100px;
    	font-size:100px;
    }
    修改成
    div{
    	width:calc( 100rem / 64 );
    	font-size:calc( 100rem / 64 );
    }
    複製代碼
  5. 將設計稿的寬度也抽象出去

    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>
複製代碼

最終效果

2019-04-30090218

小版心

小板心的作法其實也是流式佈局中的一種,只不過對最外層容器加了一個最大寬度的設置如

main{
	max-width:540px;
}
複製代碼

參考

2019-04-30090218

小程序端

小程序端能夠理解特殊的移動端,只不太小程序端不存在 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 和 vh

在移動端中,還存在如下單位,也很好用,能夠很方便解決問題。

單位 名稱
vw 100vw 等於 視口的寬度
vh 100vh 等於 視口的高度
vMax vw 和 vh 中的較大的那個
vMin vw 和 vh 中的較小的那個

以上單位 在移動端中,或者在小程序中都支持。

設計稿爲 375px,存在一個大小爲100pxdiv,字體大小也爲100px

  1. 375px = 100 vw 那麼 1 px = 100vw / 375
  2. 所以 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);
    }
複製代碼

響應式佈局

響應式的概念分爲兩大類

  1. 一種是後端響應式
  2. 一種是前端響應式

後端響應式

後臺服務器根據前端瀏覽器的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>
複製代碼

效果

2019-04-30090218

其餘

業內要實現響應式佈局時,通常會使用 推特公司的 bootstrap 框架,好評度很高,並且還針對ie8 作了兼容處理。

相關文章
相關標籤/搜索