移动端web开发

Mr.ZhaoAbout 20 min

1. 移动端基础

1.1 浏览器现状

由于移动端浏览器的发展比较晚,所以主流移动端浏览器的内核都是基于 Webkit 内核打造的

我们在进行移动端的页面开发时,兼容性主要考虑 Webkit 内核

1.2 手机屏幕现状

目前无论是 安卓 还是 IOS,移动端设备的屏幕尺寸非常多,碎片化非常严重

但是,前端页面开发者无需关注这些分辨率,因为我们常用的尺寸单位是 px

1.3 常见移动端屏幕尺寸

目前移动端的屏幕尺寸非常多,并且随着发展还会越来越多

但是,对于移动端的 Web 开发来说,我们不用考虑太多

对于专门的 安卓 和 IOS 开发,才需要特别关注 dpdpiptppi 等单位

1.4 移动端调试方法

  • Chrome DevTools(谷歌浏览器)的模拟手机调试
  • 搭建本地 Web 服务器,手机和服务器一个局域网内,通过手机访问服务器
  • 使用外网服务器,直接 IP 或 域名 访问

1.5 像素

屏幕是由一个一个发光的小点构成,这一个个的小点就是像素

分辨率:1920 x 1080 说的就是屏幕中小点的数量,横向1920个像素点,纵向1080个像素点

在前端开发中像素要分成两种情况讨论:CSS像素物理像素

物理像素,显示器的小点点就属于物理像素

CSS像素,编写网页时,我们所用像素都是CSS像素

浏览器在显示网页时,需要将CSS像素转换为物理像素然后再呈现

一个CSS像素最终由几个物理像素显示,由浏览器决定, 默认情况下在pc端,一个CSS像素=一个物理像素

2. 视口

视口(viewport):浏览器显示页面内容的屏幕区域

视口的分类:布局视口、视觉视口、理想视口

2.1 布局视口

为了解决早期 PC 端网页在手机上显示的问题,移动端浏览器都默认设置了一个布局视口(layout viewport)

IOS、Android 基本都将布局视口分辨率设置为 980px,所以 PC 上的网页大多也能在手机上呈现,但是网页元素看上去会非常小,一般可以通过手动缩放网页

移动端web开发01.png
移动端web开发01.png

2.2 视觉视口

字面意思,它是用户正在看到的网站的区域。注意:是网站的区域

我们可以通过缩放去操作视觉视口,但不会影响布局视口,布局视口仍保持原来的宽度

移动端web开发02.png
移动端web开发02.png

2.3 理想视口

发明者:史蒂夫·乔布斯

为了使网站在移动端有最理想的浏览和阅读宽度而设定

理想视口,对设备来讲,是最理想的视口尺寸

需要手动添写 meta 视口标签通知浏览器操作

meta 视口标签的主要目的:布局视口的宽度应该与理想视口的宽度一致,简单理解就是设备有多宽,我们布局的视口就有多宽

移动端 web 开发就是开发理想视口!

2.4 视口总结

  • 视口就是浏览器显示页面内容的屏幕区域
  • 视口分为布局视口、视觉视口和理想视口
  • 我们移动端布局想要的是理想视口就是手机屏幕有多宽,我们的布局视口就有多宽
  • 想要理想视口,我们需要给我们的移动端页面添加 meta 视口标签

2.5 meta视口标签

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

name="视口"

content="内容中包含若干个属性,用逗号隔开"

属性解释说明
width宽度设置的是 viewport 宽度,我们设置为 device-width “设备宽度” 特殊值
initial-scale初始缩放比,大于 0 的数字,一般来说是设置为 1:1 即:1.0
maximum-scale最大缩放比,大于 0 的数字
minimum-scale最小缩放比,大于 0 的数字
user-scalable用户是否可以缩放,yes 或 no(1或0),一般来说是 no

2.6 标准的viewport设置

  • 视口宽度和设备保存一致 device-width
  • 视口默认缩放比例 1.0
  • 不允许用户自行缩放 no
  • 最大允许的缩放比例 1.0
  • 最小允许的缩放比例 1.0

2.7 移动端完美视口

不同屏幕,单位像素的多少是不同的,单位像素越多屏幕会越清晰

默认情况下,移动端的网页都会将视口设置为 980像素(CSS像素),以确保pc端网页可以在移动端正常访问,但是如果网页的宽度超过了980,移动端的浏览器会自动对网页缩放以完整显示网页

所以基本大部分的pc端网站都可以在移动端中正常浏览,但是往往都不会有一个好的体验,为了解决这个问题,大部分网站都会专门为移动端设计网页

移动端默认情况下像素比是 980/移动端宽度,即视口宽度(css像素)/移动端物理屏幕宽度

例如:我的手机是小米6,默认情况下像素比是980/1080=0.907

如果我们直接在网页中编写移动端代码,这样在980的视口下,像素比是非常不好,导致网页中的内容非常小

编写移动页面时,必须要确保有一个比较合理的像素比:1css像素对应2个物理像素、1css像素对应3个物理像素

可以通过meta标签来设置视口宽度,控制像素比,如果这样固定视口宽度会导致在不同机型下显示效果不同

所以不能将视口宽度写死

<meta name="viewport" content="width=100px">

每一款移动设备设计时,都会有一个最佳的像素比,所以设备不同,像素比不同 一般我们只需要将像素比设置为该值即可得到一个最佳效果 将像素比设置为最佳像素比的视口大小我们称其为完美视口

<meta name="viewport" content="width=device-width">

完美视口问题

不同手机完美视口的大小是不同的

iphonex 375px

iphone6 414px

如果设置一个元素宽度为375px,在iphonex里显示正常,在iphone6中就不能占满宽度

由于不同设备视口和像素比不同,所以同样的375个像素在不同的设备下意义是不一样的

为什么不用100%呢?

在多层元素嵌套下,百分比的参照物不同,所以不能用百分比进行布局

3. 二倍图

3.1 物理像素&物理像素比

  • 物理像素点指的是屏幕显示的最小颗粒,是物理真实存在的
  • 在 PC 端页面,1px 等于 1 个物理像素,但是移动端就不尽相同
  • 移动端 1px 能实际显示的物理像素点的个数就称为物理像素比或屏幕像素比

物理像素比 = 物理像素(分辨率) / 独立像素(CSS像素)

例如:iPhone X 的物理像素比为 3

屏幕尺寸独立像素(CSS像素)物理像素(分辨率)ppi/dpi(像素密度)dpr(倍图)
5.8英寸812×3752436×11254583

浏览器放大两倍的情况:

视口宽度 960px(CSS像素) 1920px(物理像素)

此时,css像素和物理像素的比是1:2,即一个浏览器显示一个css像素宽度,物理像素用了两个像素显示(此处忽略高度),也就是100个css像素经过缩放200%后显示器显示200个像素

我们可以通过改变视口的大小,来改变CSS像素和物理像素的比值

影响视口宽度的因素有:浏览器缩放百分比系统缩放,拖动浏览器窗口

物理像素比提出的原因:

  • 在早期,PC及移动端都是:1CSS像素 = 1物理像素
  • 随着 Retina(视网膜屏幕)显示技术的普及,可以将更多的物理像素点压缩至一块屏幕里,从而达到更高的分辨率,并提高屏幕显示的细腻程度

常见 iPhone 设备屏幕参数:

设备物理分辨率开发分辨率物理像素比(dpr)
iPhone13 Pro Max、12 Pro Max1284 * 2778428 * 9263
iPhone 13\13 Pro、12\12 Pro1170 * 2532390 * 8443
iPhone 13 mini、12 mini1080 * 2340375 * 8122.88(3)
iPhone 11 Pro Max、XS Max1242 * 2688414 * 8963
iPhone X、XS、11 Pro1125 * 2436375 * 8123
iPhone XR、11828 * 1792414 * 8962
iPhone 8 Plus1080 * 1920414 * 7362.6(3)
iPhone 8、SE750 * 1334375 * 6672

常见 iPad 设备屏幕参数:

设备物理分辨率开发分辨率物理像素比(dpr)
iPad Pro 12.92048 * 27321024 * 13662
iPad Pro 111668 * 2388834 * 11942
iPad mini 8.31488 * 2266744 * 11332

随着移动智能设备屏幕素质的不断提高,目前手机一般都统一使用 3 倍图,平板电脑使用 2 倍图

电脑-显示器多倍图说明

目前由于电脑显示器的素质也越来越高(尤其是笔记本电脑),2K屏、3K屏、4K屏、5K屏、6K屏 已经在不断普及,所以其实电脑端的也已经存在多倍图的应用了

比如 Macbook Pro 16 M1 Pro/Max:物理分辨率(3456 * 2234)开发分辨率(1728 * 1117)2倍图

当然电脑端用户都能够方便的设置屏幕显示的缩放比,当缩放比为100%时就为1倍图,但目前的电脑端显示器大多已经默认为 125%、150%、175%、200% 缩放比

故,在未来多倍图的运用将会越来越必要!

认识了缩放,就能合理的解释:为什么在电脑上设置了一个 100 * 100 的 div 盒子,而在浏览器上用测量工具测量像素长度时,却为 150 * 150,因为此时电脑显示器为 150% 的缩放比,只要我们将其改为 100%,就能得到我们想要的效果了

3.2 多倍图

  • 对于一张 50px * 50px 的图片,在手机 Retina 屏中打开,按照刚才的物理像素比会放大倍数,这样会造成图片模糊(比如:3倍图手机中,50 * 50 实际上是 150 * 150 个像素在显示)
  • 在标准的 viewport 设置中,使用多倍图来提高图片质量,解决在高清设备中的模糊问题
  • 通常使用二倍图,是因为 iPhone 6\7\8 的影响,但是现在 3倍图、4倍图也逐渐普及了,这个要看实际开发需求
  • 背景图片也同样要注意缩放问题
  • 字体不用考虑缩放问题,因为字体是矢量的,不会失真
  /* 在 iphone8 下面 */
  img {
      /* 原始图片100*100px */
      width: 50px;
      height: 50px;
  }

  .box {
      /* 原始背景图片100*100px */
      background-size: 50px 50px;
  }

案例:

<!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>03-二倍图做法</title>
    <style>
        /* 我们需要一个50*50像素(css像素)的图片,直接放到我们的iphone8里面会放大2倍100*100就会模糊 */
        /* 我们采取的是放一个100*100图片,然后手动的把这个图片缩小为50*50(css像素)*/
        /* 我们准备的图片比我们实际需要的大小大2倍,这就方式就是2倍图 */
        img:nth-child(2) {
            width: 50px;
            height: 50px;
        }
    </style>
</head>

<body>
    <!-- 模糊的 -->
    <img src="images/apple50.jpg" alt="">
    <!-- 我们采取2倍图 -->
    <img src="images/apple100.jpg" alt="">
</body>

</html>

3.3 背景缩放

background-size 属性规定背景图像的尺寸

background-size: 背景图片宽度 背景图片高度;
  • 单位:长度 | 百分比 | cover | contain
  • cover 把背景图像扩展至足够大,以使背景图像完全覆盖背景区域
  • contain 把图像扩展至最大尺寸,以使其宽度和高度完全适应内容区域

注意:

  1. 以长度为单位时,只写其中一个参数,另一个参数会自动适配
  2. 以百分比为单位时,其参照对象为父盒子,只写其中一个参数,另一个参数会自动适配

4. 移动端开发选择

4.1 移动端主流方案

4.2 单独移动端页面(主流)

通常情况下,网址域名前面加 m(mobile) 可以打开移动端

通过判断设备,如果是移动设备打开,则跳到移动端页面

4.3 响应式兼容移动端(其次)

通过判断浏览器窗口宽度来改变样式,以适应不同终端

缺点:制作麻烦,需要花很大精力去调兼容性问题

5. 移动端技术解决方案

5.1 移动端浏览器

  • 移动端浏览器基本以 webkit 内核为主,因此我们就考虑 webkit 兼容性问题
  • 我们可以放心使用 HTML5标签和CSS3样式
  • 同时我们浏览器的私有前缀我们只要考虑添加 webkit 即可

5.2 移动端特殊样式

/* CSS3盒子模型 */
box-sizing: border-box;
-webkit-box-sizing: border-box;	/* 浏览器前缀兼容老版本浏览器 */

/* 移动端中某些地方点击会高亮,我们一般需要清除,设置 transparent 完成透明 */
/* 说明:比如 a链接 在移动端默认点击时会有一个背景颜色高亮 */
-webkit-tap-highlight-color: transparent;
/* 比如可以这样: */
* {
    -webkit-tap-highlight-color: transparent;
}

/* 移动端浏览器默认的外观在 iOS 上加上这个属性才能给按钮和输入框自定义样式 */
-webkit-appearance: none;
/* 比如可以这样: */
input  {
    -webkit-appearance: none;
}

/* 禁用长按页面时的弹出菜单 */
-webkit-touch-callout: none;
/* 此处以 img 及 a 为例子 */
img, a { -webkit-touch-callout: none; }

6. 移动端常见布局

移动端布局和以前我们学习的PC端有所区别:

  • 单独制作移动端页面【主流】

    • 流式布局(百分比布局)

    • flex 弹性布局(强烈推荐)

    • less + rem + 媒体查询布局

    • 混合布局

  • 响应式页面兼容移动端【其次】

    • 媒体查询

    • bootstrap

6.1 流式布局(百分比布局)

  • 流式布局,就是百分比布局,也称非固定像素布局
  • 通过盒子的宽度设置成百分比来根据屏幕的宽度来进行伸缩,不受固定像素的限时,内容向两侧填充
  • 流式布局方式是移动Web开发使用的比较常见的布局方式
  • max-width 最大宽度(max-height 最大高度)
  • min-width 最小宽度(min-height 最小高度)

案例:

<!doctype html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>08-流式布局</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        section {
            width: 100%;
            max-width: 980px;
            min-width: 320px;
            margin: 0 auto;
        }

        section div {
            float: left;
            width: 50%;
            height: 400px;
        }

        section div:nth-child(1) {
            background-color: pink;
        }

        section div:nth-child(2) {
            background-color: rgb(0, 0, 0);
        }
    </style>
</head>

<body>
    <section>
        <div></div>
        <div></div>
    </section>
</body>

</html>

6.2 rem适配布局

6.2.1 rem与媒体查询

【思考】

  1. 页面布局文字能否随着屏幕大小变化而变化?

  2. 流式布局和 flex 布局主要针对于宽度布局,那高度如何设置?

  3. 怎么样让屏幕发生变化的时候元素高度和宽度等比例缩放?

rem(root em)是一个相对单位,类似于 emem 是父元素字体大小

不同的是 rem 的基准是相对于 html 元素的字体大小

比如,根元素(html)设置 font-size=12px,非根元素设置 width: 2rem; 则换成 px 表示就是 24px

rem 的优势:父元素文字大小可能不一致,但是整个页面只有一个 html,可以很好来控制整个页面的元素大小(即:达到统一控制全局字体大小的效果!)

注意:rem 控制的不仅仅是字体大小,还能控制其他元素的大小。

/* 根 html 为 12px */
html {
    font-size: 12px;
}
/* 此时 div 的字体大小就是 24px */
div {
    font-size: 2rem;
}

【案例】

<!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>rem单位</title>
    <style>
        html {
            font-size: 12px;
        }

        div {
            font-size: 12px;
            width: 15rem;
            height: 15rem;
            background-color: purple;
        }

        p {
            /* 1. em 相对于父元素的字体大小来说的 */
            /* 
            width: 10em;
            height: 10em;
            */
            /* 2. rem 相对于 html 元素字体大小来说的 */
            width: 10rem;
            height: 10rem;
            background-color: pink;
            /* 3.rem 的优点就是可以通过修改 html 里面的文字大小来改变页面中元素的大小可以整体控制 */
        }
    </style>
</head>

<body>
    <div>
        <p></p>
    </div>
</body>

</html>

注:虽然使用 rem 之后实现了全局字体大小的统一控制,但是依旧不能根据窗口大小自动适配,需要使用媒体查询

rem 单位是跟着 html 来走的,有了 rem 页面元素可以设置不同大小尺寸

媒体查询可以根据不同设备宽度来修改样式

媒体查询 + rem就可以实现不同设备宽度,实现页面元素大小的动态变化

案例:

<!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>媒体查询+rem实现元素动态变化</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        /* html {
            font-size: 100px;
        } */
        /* 从小到大的顺序 */

        @media screen and (min-width: 320px) {
            html {
                font-size: 50px;
            }
        }

        @media screen and (min-width: 640px) {
            html {
                font-size: 100px;
            }
        }

        .top {
            height: 1rem;
            font-size: .5rem;
            background-color: green;
            color: #fff;
            text-align: center;
            line-height: 1rem;
        }
    </style>
</head>

<body>
    <div class="top">购物车</div>
</body>

</html>

6.2.2 rem适配方案

【思考】

  1. 我们适配的目标是什么?
  2. 怎么去达到这个目标的?
  3. 在实际的开发如何实现?

【答案】

  1. 让一些不能等比自适应的元素,达到当设备尺寸发生改变的时候,等比例适配当前设备
  2. 使用媒体查询根据不同的设备按比例设置 html 的字体大小,然后页面元素使用 rem 做尺寸单位,当 html 做尺寸单位,当 html 字体大小变化元素尺寸也会发生变化,从而达到等比缩放的适配
  3. 实际开发中
    1. 按照设计稿与设备宽度的比例,动态计算并设置 html 根标签的 font-size 大小(媒体查询)
    2. CSS 中,设计稿元素的宽、高、相对位置等取值,按照同等比例换算为 rem 为单位的值

主要有两种方案:

  1. 技术方案1

    • less

    • 媒体查询

    • rem

  2. 技术方案2

    • vw
    • rem
6.2.2.1 方案1

rem + 媒体查询 + less

(1)设计稿常见尺寸宽度

设备常见宽度
iphone 4 5640px
iphone 6 7 8750px
iphone x 11 121170px
Android常见 320px、360px、375px、384px、400px、414px、500px、720px、1080px

一般情况下,我们以一套或两套效果图适应大部分的屏幕,放弃极端屏或对其优雅降级,牺牲一些效果,现在基本以 750px 为准。(目前应该是 1080px)

(2)动态设置 html 标签 font-size 大小

  1. 假设设计稿是 750px
  2. 假设我们把整个屏幕划分为 15 等份(划分标准不一,可以是 20 份,也可以是 10 等份)
  3. 每一份作为 html 字体大小,这里就是 750/15 = 50px
  4. 那么在 320px 设备的时候,字体大小为 320/15 = 21.33px
  5. 用我们页面元素的大小除以不同的 html 字体大小会发现他们比例还是相同的
  6. 比如我们以 750px 设计稿
  7. 此时便实现了不同屏幕下页面元素盒子等比例缩放的效果

(3)元素大小取值方法

  1. 最后的公式:页面元素的 rem 值 = 页面元素值(px) / (屏幕宽度 / 划分份数)
  2. 屏幕宽度 / 划分份数 = html font-size 的大小
  3. 或者:页面元素的 rem 值 = 页面元素值(px) / html font-size 字体大小

【案例】

<!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>rem适配方案</title>
    <style>
        @media screen and (min-width: 320px) {
            html {
                font-size: 21.33px;
            }
        }

        @media screen and (min-width: 750px) {
            html {
                font-size: 50px;
            }
        }

        div {
            width: 2rem;
            height: 2rem;
            background-color: pink;
        }

        /* 1. 首先我们选一套标准尺寸 750px 为准 
           2. 我们用屏幕尺寸 除以 我们划分的份数 得到了 html 里面的文字大小 但是我们知道不同屏幕下得到的文字大小是不一样的 */
        /* 3. 页面元素的 rem值 =  页面元素在 750 像素的下px值 / html 里面的文字大小 */
    </style>
</head>

<body>
    <div></div>
</body>

</html>
6.2.2.2 方案2

vw表示的是视口的宽度(viewport width)

  • 100vw = 一个视口的宽度
  • 1vw = 1%视口宽度

vw单位永远参考于视口宽度进行计算

常规的设计图宽度750px,使用vw如何通过设计图中的大小来设计网站大小

设计图中48x35像素大小的元素如何在页面中保证元素大小

100vw = 750px (设计图中像素)

0.1333333333333333333vw = 1px

0.13333333333vw x 48px = 6.4vw

0.13333333333vw x 35px = 4.66666666666vw

如果根据设计图像素计算vw , 必须通过0.133333333333*px ,数值的换算非常不方便

1rem = 1 html的字体大小

能否将font-size设置为0.1333333333来方便设置vw呢?

font-size: 0.1333333333333333vw;

网页中字体大小最小是12px,不能设置一个比12像素还小的字体

如果我们设置了一个小于12px的字体,则字体自动设置为12

现在将font-size 扩大100倍

font-size: 13.33333333333333vw;

每次使用时设计图像素除100

0.01rem = 1px 也可以用设计图像素乘以0.01

width: 0.48rem;
height: 0.35rem;

6.3 vw布局

移动端推荐使用:flex + less + vw

6.3.1 vw/vh是什么

  • vw/vh 是一个相对单位(类似 em 和 rem 相对单位)
    • vw 是:viewport width 视口宽度单位
    • vh 是:viewport height 视口高度单位
  • 相对视口的尺寸计算结果
    • 1vw = 1/100 视口宽度
    • 1vh = 1/100 视口高度

例如:

当前屏幕视口是 375px,则 1vw 就是 3.75px,如果当前屏幕视口为 414px,则 1vw 就是 4.14px

注意:和百分比有区别,百分比是相对于父元素来说的,而 vw 和 vh 总是针对于当前视口来说的

6.3.2 vw/vh怎么用

  • 超级简单,元素单位直接使用新单位 vw/vh 即可
  • 因为 vw/vh 是相对单位,所以不同视口(屏幕)下,宽高一起变化完成适配

直接使用即可!永远滴神!

【案例】

div {
    width: 10vw;
    height: 10vh;
    background-color: pink;
}

如何还原设计稿?

前提:我们设计稿按照 iPhone 6/7/8 来设计,有个盒子是 50px * 50px 的,如何使用 vw 呢?

分析:

  1. 设计稿参照 iPhone 6/7/8,所以视口宽度尺寸是 375px(设计原型图平台切换到 2x 模式再测量,因为 UI 设计图是 750px 的)

  2. 那么 1vw 是多少像素?

    375px / 100 = 3.75px

  3. 我们元素的目标是多少像素?

    50px * 50px

  4. 那么 50 * 50 是多少个 vw?

    50 / 3.75 = 13.3333vw

在 UI 软件中,直接选择 vw 单位然后测量即可,不用人工计算

6.3.3 vw注意事项

因为涉及到大量除法且有除不尽的情况,所以还是使用 LESS 搭配更好点

我们本质是根据视口宽度来等比例缩放页面元素高度和宽度的,所以开发中使用 vw 就基本够用了。vh 很少使用(高度变化时,我们一般不需要元素大小进行变化,所以用不到 vh)

div {
    /* 都用vm */
    width: 13.333333vw;
    height: 12.666666vw;
    font-size: 5.333333vw;
    background-color: pink;
}