适配方案(一)之移动端适配

移动端

特色

移动端下的屏幕存在如下特色:javascript

  • 屏幕相比较于PC端要小css

  • 浏览器不像PC端,随时各类调整大小html

缘由

移动端因为屏幕总体比PC端小,并且也不能出现拖动浏览器来调整大小的状况,因此在移动端上的布局是流式布局最多,其中有些小分支,如固定小版心。前端

案例

代码

普通的图片和容器,写单位的时候换成 百分比 或者 flex便可。java

对于页面中的某些元素,如字体大小,可使用 淘宝 flexibile + rem 的解决方案android

1、普通的流式布局

<!DOCTYPE html>
<html lang="en">css3

<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;
  }nginx

  body {
    background-color: #ccc;
  }git

  ul {
    list-style: none;
    display: flex;
    height: 100px;
  }github

  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>

效果

2、淘宝flexible + rem

flexible 和flex布局不要紧 老婆和老婆饼 也没有关系

这个解决方案是能够和以上的流式布局搭配使用的,rem的做用是主要是针对字体实现 跟随屏幕变化而变化

  • rem css单位,相对长度,它的值等于根标签的字体大小
  • 淘宝flexible

   是手淘团队出的一个处理移动端rem设置的js库

     把根标签的字体大小改为了 当前屏幕的十分之一大小

     根标签的字体大小发生改变了,使用了rem单位的元素或者字体大小也跟着改变

手机淘宝的flexible方案,特色:

1.仅针对iphone生成动态viewport,由于目前iphone的dpr只有1,2,3三种,android的dpr颇有多种,不具备一致性;

2.字体大小不用rem作缩放处理,仍然使用px单位,设置不一样dpr下对应的字体大小;

3.宽度利用rem等比缩放;

4.容许强制定义dpr;

使用时页面头部须要引入flexible.js.

 

流程

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;

  // 设置body元素字体大小:监听DOM内容是否加载完毕,完毕后给body设置字体大小

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

综合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;

  // 设置body元素字体大小:监听DOM内容是否加载完毕,完毕后给body设置字体大小

  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>

最终效果

3、小版心

小板心的作法其实也是流式布局中的一种,只不过对最外层容器加了一个最大宽度的设置如

main{
  max-width:540px;
}

参考

4、vw 和 vh

在移动端中,还存在如下单位,也很好用,能够很方便解决问题。

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

设计稿为 375px,存在一个大小为100pxdiv,字体大小也为100px

  • 375px = 100 vw 那么 1 px = 100vw / 375

  • 所以 100px = 100vw * 100 / 375;

代码

main {
  background-color: pink;
  width: calc(100vw * 100 / 375);
  height: calc(100vw * 100 / 375);
  font-size: calc(100vw * 100 / 375);
}

详细介绍

老版常规作法

方案一:Meida Queries媒体查询

meida queries 主要是经过查询设备的宽度来执行不一样的 css 代码,最终达到界面的配置。核心语法是:

@media screen and (max-width: 600px) { /*当屏幕尺寸小于600px时,应用下面的CSS样式*/ /*你的css代码*/ }

须要添加meta设置

<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">

width=device-width :表示宽度是设备屏幕的宽度

initial-scale=1.0:表示初始的缩放比例

minimum-scale=1.0:表示最小的缩放比例

maximum-scale=1.0:表示最大的缩放比例

user-scalable=no:表示用户是否能够调整缩放比例

这个标签能够保证在移动端设备中,页面的宽度与屏幕宽度相同。

方案二:px + viewport缩放

以最小的Iphone4/5的宽度(320px)为基准,还原视觉稿。

<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0 />

而后对不一样屏幕分辨率的手机进行简单粗暴的等比例缩放设置。 例如:iphone8(375px)initial-scale = 375 / 320 = 1.18

<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.18 />

initial-scale愈来愈大,页面内容也就被拉伸也越厉害,致使页面内容会变得模糊,这个方法已经被摒弃了。

高度定死,宽度自适应,元素都采用px作单位。

随着屏幕宽度变化,页面也会跟着变化,效果就和PC页面的流体布局差很少,在哪一个宽度须要调整的时候使用响应式布局调调就行(好比网易新闻),这样就实现了『适配』

方案三:响应式布局

响应式的概念分为两大类

  • 一种是后端响应式

  • 一种是前端响应式

后端响应式

后台服务器根据前端浏览器的User-Agent来判断来源请求是PC端仍是移动端,而后服务器动态返回PC端页面或者移动端页面。nginx中很容易就出现该功能。京东,天猫,淘宝也是这样子的。

前端响应式

主要是指经过媒体查询来实现。

前端写好一套代码 html + css + javascript ,就能够冬天的根据屏幕的宽度来改变页面的样式

这种作法体验不是最好,可是倒是最小的代码实现了 兼容pc端和移动端。通常是对页面要求不高或者小企业使用。

因为还要兼容到pc端,因此通常作响应式页面 不会用过高级的h5 css3 的技术。

新作法

方案四:rem + viewport缩放

须要添加meta设置

<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">

 

换句话说,当咱们指定一个元素的font-size为2rem的时候,也就说这个元素的字体大小为根元素<html>字体大小的两倍,若是html的font-size为12px,那么这个2rem的元素font-size就是24px。同理当该元素为3rem时,那么其实际

font-size就是36px

html {font-size: 12px;}

h1 { font-size: 2rem; } /* 2 × 12px = 24px */

p { font-size: 1.5rem;} /* 1.5 × 12px = 18px */

div {width: 20rem;} /* 20 * 12px = 240px*/

看到这里你应该就会发现,只要咱们根据不一样屏幕设定好根元素<html>的font-size,其余已经使用了rem单位的元素就会自适应显示相应的尺寸了。 

rem计算

咱们使用rem单位事先须要作的一件事情就是设置根元素<html>的font-size,一般有两种作法

方法一:JS计算

经过JavaScript读取屏幕宽度,而后根据宽度计算出对应的尺寸并设置根元素的font-size。

const oHtml = document.getElementsByTagName('html')[0]

const width = oHtml.clientWidth;

// 320px的屏幕基准像素为12px

oHtml.style.fontSize = 12 * (width / 320) + "px";

这样iphone8(375px)下html的font-size 就是14.0625px,iphone8p下font-size就是15.525px。

若是在iphone8(375px)下设置元素font-size为 1.7066rem, 效果跟设置其font-size为 24px 是同样的(24 / 14.0625 = 1.7066)。

使用JS来获取屏幕宽度的好处在于能够100%适配全部的机型宽度,由于其<html>元素的基准尺寸是直接算出来的。既然是JS代码,为了不形成由于动态设置<html>元素的font-size而形成页面抖动,通常这部分代码咱们放在header

底部去加载,并内联到html文档里面。

方法二:媒体查询

既然只是为了根据屏幕宽度来设置<html>元素的字体大小,那咱们彻底也能够经过css3媒体查询来完成这部分工做。

@media screen and (min-width: 375px){

   html { font-size: 14.0625px; }

}

@media screen and (min-width: 360px){

  html { font-size: 13.5px; }

}

@media screen and (min-width: 320px){

html { font-size: 12px; }

}

html { font-size: 16px; }

rem存在的问题

rem做为一种简单粗暴解决不一样屏幕下视图的区别的一种方案,它能够解决本文出现的问题以及绝大多数移动端适配屏幕尺寸的问题。可是既然它并非一个完美的解决方案,那就有其局限性所在。

大屏智能机时代确实几乎彻底替代了我十年前纸质化阅读的习惯。从2011年至今,手上的手机屏幕宽度一直在提高,可是使用的看小说软件的显示字号几乎是不变的。使用rem会在必定程度上打破用户的文字内容阅读习惯,特别是在大篇

幅的内容时。

iOS与Android平台的适配方式背后隐藏的设计哲学是这样的:阅读文字时,可读性较好的文字字号行距等绝对尺寸数值组合与文字所在媒介的绝对尺寸关系不大。(能够这样简单理解:A4大小的报纸和A3大小甚至更大的报纸,温馨的阅

读字号绝对尺寸是同样的,由于他们都须要拿在手里阅读,在手机也是上同理);在看图片视频时,图片、视频的比例应该是固定的,不该该出现拉伸变形的状况。而rem用在字号时,使字号在不一样屏幕上的绝对尺寸不一致,违背了设计

哲学。

方案五:vw + vh

参考

简单粗暴的移动端适配方案 - REM

阿里巴巴TXD移动端适配总结(viewport讲的不错)

浅谈-web屏幕适配的解决方案

相关文章
相关标签/搜索