关于移动端适配的三种方案.

移动端适配,主要是适配手机和一些平板设备.

为什么需要适配呢?

在客观条件上,这些设备的物理宽度都是不一致的.

比如手机的宽度就有 3xx | 4xx | 5xx 等.

如果按照我们常用的 width = xxxpx 肯定是不行的.

比如我们在一个 320 宽度的设备上,设置某个元素的宽度是 80px

我们这么设置的理由是: 希望在屏幕上可以横向摆列4个这样的元素.

但是在在不是320宽度的设备上,这么写直接写80px是肯定不行的.

补充: 所有的设备都包含两种像素类别。 【物理像素】和【逻辑像素】。
物理像素:设备屏幕实际的物理像素点,就是那块显示板子上,实际上焊接了多少个可以用于显示颜色的小点元件。
逻辑像素: 我们在代码中写的多少px,其实就是写的逻辑像素。
很早之前,当Apple还没推出retina屏幕之前,逻辑像素和物理像素是一对一的关系,也就是一个逻辑像素就对应一个物理像素。
现在市面上高清屏幕越来越多(这里指的是物理显示颜色的小点原件越来越多),所以逻辑像素和物理像素就不是一比一的关系了。
比如:iPhone 8 的逻辑像素的375 * 667 。但是那块4.7英寸的屏幕上,实际焊接了 750 * 1334 个显示颜色的原件。
于是,逻辑像素和物理像素,不在是一比一的关系。所以就引出来了一个新的概念,dpr(device pixel ratio),也就是所谓的设备像素比
计算公式为:物理像素 / 逻辑像素 = dpr。于是,就可以知道iPhone 8 的 dpr = 2 ,iPhone 8 Plus 的 dpr 是 3。
也就是说,物理像素一定是大于或等于逻辑像素的。当dpr > 1 ,就说明,这块屏幕是个高清屏。一个逻辑像素点对应 dpr^2 个物理像素。


移动端适配方案一 --- 百分比适配

在移动端适配的方案里,百分比适配方案是最容易理解的一种.

我们都知道设置某个元素的宽高百分比,是根据其父容器的宽高来进行的(局限:父元素宽高已知).

比如,我们在一个希望在所有的移动端设备里,不管屏幕宽度是多少,都希望一行能排列4个元素,并刚好占满.

我们只需要设置每个元素的宽度是 25% 即可.

* {
      margin: 0;
      padding: 0;
    }
    div {
      width: 25%;
      float: left;
      height: 100px;
    }

    .box1 {
      background-color: red;
    }
    .box2 {
      background-color: yellow;
    }
    .box3 {
      background-color: green;
    }
    .box4 {
      background-color: orange;
    }

<div class="box1"></div>
<div class="box2"></div>
<div class="box3"></div>
<div class="box4"></div>

在 3xx 4xx 5xx 里面宽度显示都没问题.

宽度百分比适配
但是问题来了.

对于宽度的计算,百分比确实能够做到非常完美的适配(父容器宽度已知的情况下). 

**但是高度呢?**

比如在 320 屏幕里,我设置的高度是 `100px`.

根据比例计算
+ 在 375 宽度的屏幕设备里,高度应该是 375 * 100 / 320 = 117.19px
+ 在 414 宽度的屏幕设备里,高度应该是 414 * 100 / 320 = 129.375px

像上述那样写死 100px 的高度,肯定就不行了.

**所以使用百分比适配,可以适配元素的宽度,但是高度无法适配.**

且即使是宽度,也只能是在父容器宽度已知的条件下,百分比设置宽度才有效果.

移动端设备适配方案二 --- viewport 视口适配

说 viewport 视口适配之前,先来说说什么是viewport.

viewport 是移动端开发中,非常重要的一个 meta 设置标签.它用于初始化当前移动端设备的宽度,初始缩放比例,用户是否可缩放等一系列指令.

如果,我们在移动端开发的情况下,没有加这个标签,来指定设备的宽度.

// 只要是 width=device-width
<meta name="viewport" content="width=device-width, initial-scale=1.0">

那么,基本上所有移动端设备的宽度会被设置成 980px..

我们又一般有PC的经验,会把字体设置成16px.

所以,在一个移动端设备由于没有加 viewport ,默认宽度是 980 px, 字体又被我们习惯性的设置成 16px. 就会出现字体非常小,根本无法阅读的情况.

移动端不设置viewport,默认宽度是980px

viewport 视口适配的方案的核心在于:给定一个目标的屏幕宽度,然后根据当前设备实际的屏幕宽度进行缩放比例的设置.

  • 按照一个固定的屏幕宽度来进行适配.
  • 比如,我写的设备宽度就是320.
  • 那么一个1/4屏幕的宽度就是80px.(我像素就写80px)
  • 如果正好在一个320,那么刚好就是1/4.没毛病.
  • 如果是在一个屏幕宽度为640的设备上,写死80px,就只能占1/8. 解决办法就是,把640设备的初始比例设置成2倍.(对,没错,就是放大两倍显示)
  • 对于一个160宽度屏幕的设备,我们就缩小两倍显示.

上述那个比例计算,是根据当前设备的屏幕宽度来的.所以肯定需要动态计算.


(function () {
    let screenW = window.screen.width // 获取当前设备屏幕宽度
    let targetWidth = 320 // 目标宽度
    let scale = screenW / targetWidth // 当前设备屏幕宽度 / 目标宽度  = 缩放比例 (640=2,160=0.5)
        
    // 然后根据计算出来的结果,初始化当前设备的缩放比例.
    let meta = document.createElement('meta')
    meta.name = 'viewport' // 视口设置的meta
    meta.content = 'user-scalable=no,initial-scale=${scale},maximum-scale=${scale},minimum-scale=${scale}'
    document.head.appendChild(meta)
})()

有了上述这段代码,在所有的设备里,都会进行比例缩放.

所以,我们可以安心的在自己的css代码里写死像素了(反正小了就放大,大了就缩小).

* {
      margin:0;
      padding: 0;
    }

    div {
      width: 80px; /* 宽度80px 写死 */
      float: left;
      height: 100px; /* 高度 100px 写死 */
    }

    .box1 {
      background-color: red;
    }
    .box2 {
      background-color: yellow;
    }
    .box3 {
      background-color: green;
    }
    .box4 {
      background-color: orange;
    }

<div class="box1"></div>
<div class="box2"></div>
<div class="box3"></div>
<div class="box4"></div>

pixel2

pixel2

iPhone 4

iPhone 4

iPad

iPad

注意:

使用 viewport 进行初始比例的设置进行适配,千万不好在 viewport 里设置 width=device-width.


移动端适配方案三 --- rem 适配.

rem 是什么 ?

Relative to font-size of root Element

相对于根元素的字体大小.

在一个HTML元素中,根元素就是 <html> 标签.

所以 rem 等于设置到 html 上 font-size 的大小.

比如:

  • html 的 font-size 设置成了 16 px, 那么 1rem = 16px.
  • html 的 font-size 设置成了 100px , 那么 1rem = 100px.

这么粗看一下,好像觉得这个rem很无聊.

但是实际上, font-size = 16 px , 这里其实指的更多的是一个字的宽度.一个字的宽度是16px.

宽度是什么? 宽度是屏幕的尺寸单位!!

如果有一个设备的宽度是160px. 我设置html.font-size=16px.

那么我就可以理解成,利用rem,将这个屏幕的宽度按比例的分割成了10份.

Rem

如果是 320 宽度的设备,想平分成10分呢? html.font-size = 32px

所以,对于 rem 的设置仍然是先获取当前设备的宽度,并动态计算.

(function () {
      // 根据不同设备,将屏幕按照比例分割成10份.
      let screenWidth = document.documentElement.clientWidth || window.screen.width
      let oneRem = screenWidth / 10
      document.documentElement.style.fontSize = `${oneRem}px`
})()

查看结果:

iPhone 5

iPhone 5

iPad

iPad

现在已经成功的将设备按照屏幕宽度平均分成了10分.

那么接下来的所有布局,就可以完全按照屏幕宽度的刻度来进行了.

比如,有这么一个布局.

元素的宽度是屏幕宽度的一半(5rem),高度是屏幕宽度的1/5(2rem)

 * {
      padding: 0;
      margin: 0;
    }

    div {
      width: 5rem; /* 比例=当期那设备宽度的一半 */
      height: 2rem; /* 比例=当前设备宽度的1/5 */
      float: left;
    }
    .box1 {
      background-color: red;
    }

    .box2 {
      background-color: orange;
    }

<div class="box1"></div>
<div class="box2"></div>

查看结果:

iPad

iPad

iPhone 4

iPhone 4

未完待续...

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 161,873评论 4 370
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,483评论 1 306
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 111,525评论 0 254
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,595评论 0 218
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 53,018评论 3 295
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,958评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,118评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,873评论 0 208
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,643评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,813评论 2 253
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,293评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,615评论 3 262
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,306评论 3 242
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,170评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,968评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,107评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,894评论 2 278