移动端开发(web app) 之移动端布局 知识总结

App 分类

图片描述

如上图,Native app 是使用原生开发的 app, 优势是性能更好,还能调用系统的 api ,可是发布 app 流程繁琐,并且不跨平台。css

Web app, 优势是跨平台,修改方便,缺点是不能调用原生的 api, 并且用户体验不如原生 app, 好。html

Hybrid app, 结合了上面两个的优势,能够说是很 nice。android

尺寸相关概念

CSS 像素

又称为设备独立像素、逻辑像素。CSS中使用的一个抽象的概念,单位是 pxios

值是相对的,并非绝对的,根据 dpr 来肯定一个 CSS 像素表明几个物理像素,还有一些状况,例如用户缩放的时候,,dpr 也会跟着变为 2, 此时一个 CSS 像素表明两个物理像素。css3

注意: 电脑当中的一个设备像素通常是等于一个 CSS 像素。因此咱们在 PS 当中的切图大小,通常也表明物理像素表示的大小。web

设备像素

又称为物理像素,任何设备屏幕的物理像素的数量自出场开始就是固定不变的,单位是 pt(点)。一个物理像素即屏幕上一个发光的点。物理像素单个点的大小由厂商决定,大小不固定。api

屏幕尺寸

指的是屏幕对角线的长度,单位为英寸,注意英寸是长度单位,不是面积单位。1英寸(inch)=2.54厘米(cm)浏览器

屏幕尺寸=屏幕斜边的像素/PPI。app

图片描述

像素密度 PPI

单位面积上(英寸)像素(设备像素)的数量。它是一个定值,是一个固定的参数。PPI=屏幕斜边的像素/屏幕尺寸。以下:dom

图片描述

因此要提升 PPI的话,须要增长水平和竖直方向的像素点数量。所以,同一尺寸(inch)下,PPI提升了一倍,那像素会变为原来的4倍,也就是所 PPI 增长 N 倍,单位面积上的像素点的数量变为原来的 N^N 倍,以下图。查询不一样设备的 ppi

图片描述

PPI 的值越高,表明在必定尺寸的屏幕上像素数量越多,屏幕越清晰。以下同一张图片。

图片描述

但同时,因为单位面积(英寸)并无变,因为 PPI 的变大,对应的物理像素点会缩小。和上面的物理像素点的规律相反,PPI 增长 N 倍,单位面积上的像素点的大小将变为原来的 1 / N^N 倍。以下图:

图片描述

同时对于一张图像,放到比当前 PPI 大的设备上时,也将按照上面的比例变小。例如一个放到一个 PPI 为本身的 2 倍的设备上时,图像将缩小四倍,以下图。

图片描述

可是在实际当中咱们更但愿图片保持原有大小,而且最好是也不变模糊,保持原有的清晰度。对于上面的状况,解决方案是设备的 DPR 须要是原来设备的 2 倍,即便一个 CSS 像素须要表明的物理像素点须要变为原来的 2 倍,这就保持了图像的大小未发生改变,同时图片的分辨率也须要变为原来的两倍,这样就保持图像的清晰度未发生改变。

像素比 DPR

DPR=物理像素/css像素。获取:window.devicePixelRatio查询1查询2

它的本质是指一个 CSS 像素表明几个 物理像素。它的意义是为了让图像可以早高清屏上显示。

其实上当像素比超过 2 后,肉眼是识别不出来的。

视口 ViewPort

只针对 PC 端的页面直接放到移动端的状况的话,默认会进行缩小。首先是由于移动端的像素点通常比 PC 端更加的密集,因此相应的物理像素点都会变得很小,同时在这个缩放的基础之上,浏览器还会根据状况继续进行缩小。缩放比=物理像素(即设备像素)/ 视口宽度(html 的宽度,默认是 980px, 用document.documentElement.clientWidth方法获取)。因此在移动端开发的时候,咱们须要正确的设置 ViewPort的值。

典型的 ViewPort 的设置值为下面这样:

<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no">
  • width: device-width(设备的实际宽度--即设备的 css 像素)。
  • user-scalable: 是否容许用户在设置或者默认的视口宽度上进行页面缩放,值为no或yes,表明不容许与容许。
  • initial-scale: 页面初始缩放值,值为一个数字(能够带小数)。
  • minimum-scale: 页面最小可以缩放的比例,值为一个数字(能够带小数)。
  • maximum-scale: 页面最大可以缩放的比例,值为一个数字(能够带小数)。

须要注意的是,在移动端,若是不限制缩放,那么为了保证页面所有可见,会对页面总体进行缩放, 缩放的计算方式为: 缩放比(initial-scale)=css像素(设备css像素)/viewport宽度(html宽度)

initial-scale = 1,能够达到和 width=device-width, 同样的效果。若是都设置了,取二者的最大值。

通常当咱们都禁止用户进行缩放,以下:

minimum-scale=1,maximum-scale=1,user-scalable=no

通常根据上面的公式,咱们能够经过设置缩放比,动态的设置 viewport 的宽度。

meta 标签

禁止识别电话与邮箱(可是邮箱没效果)
            <meta name="format-detection" content="telephone=no,email=no" />

            设置添加到主屏后的标题(ios)
            <meta name="apple-mobile-web-app-title" content="标题">

            添加到主屏幕后,全屏显示,删除苹果默认的工具栏和菜单栏(无用)
            <meta name="apple-mobile-web-app-capable" content="yes" />

            放在桌面上的logo
            <link rel="apple-touch-icon-precomposed" href="iphone_logo.png" />

            启动时候的画面(无用)
            <link rel="apple-touch-startup-image" href="logo_startup.png" />

            设置x5内核浏览器只能竖屏浏览(只有UC有效)
            <meta name="x5-orientation" content="portrait" />
            
            设置x5内核浏览器全屏浏览
            <meta name="x5-fullscreen" content="true" />
            
            设置UC浏览器只能竖屏浏览
            <meta name="screen-orientation" content="portrait">
            
            设置UC浏览器全屏浏览
            <meta name="full-screen" content="yes">
            若是想屏蔽全部浏览器的横屏的话,须要在后面陀螺仪那章节讲

移动端样式重置

一、禁止用户选中文字,安卓无效(在事件那章解决,包括长按的时候会出菜单,用阻止touchstart后的默认行为搞定)
                    -webkit-user-select: none;
二、禁止长按弹出系统菜单
                    -webkit-touch-callout: none;
三、去除android下a/button/input标签被点击时产生的边框 & 去除ios下a标签被点击时产生的半透明灰色背景
                    -webkit-tap-highlight-color: rgba(0,0,0,0);
四、切换横竖屏或者用户本身经过浏览器设置的话,能够改变字体的大小(须要给body下的全部元素)
                    -webkit-text-size-adjust: 100%;
五、按钮在ios下都是圆角
                    -webkit-appearance: none;    //button与input都会有个默认背景
                    border-radius: 0;    //input有个默认圆角
六、修改placeholder的样式
                    input::-webkit-input-placeholder{
                        color:#000;    //默认的样式
                    }
                    input:focus::-webkit-input-placeholder{
                        color:#f00;    //点击后的样式
                    }
七、字体
                    ios
                        默认中文字体是Heiti SC
                        默认英文字体是Helvetica
                        默认数字字体是HelveticaNeue
                        无微软雅黑字体
                    android
                        默认中文字体是Droidsansfallback
                        默认英文和数字字体是Droid Sans
                        无微软雅黑字体
                    
                    font-family: helvetica;

移动端适配

适配是为了一版设计稿走天下,适配的范围包括字体、宽高、间距、图像

在熟悉了解了前面的概念以后,下面就来介绍移动端的适配几种方式。

百分比适配

根据父级设置宽度。可是有时候百分比不太好算,并且计算的时候须要知道父级的高度。

viewport 缩放适配

把全部机型的 css 像素设置成一致的,那么切图的时候只须要切一种尺寸的就能够了。代码以下

(function(){
                //获取css像素(viewport没有缩放)
                var curWidth=document.documentElement.clientWidth;
                var targetWidth=375; // 最终尺寸
                var scale=curWidth/targetWidth; // 缩放比
                var view=document.getElementById('view');
                view.content='initial-scale='+scale+',user-scalable=no,minimum-scale='+scale+',maximum-scale='+scale+''; // 这样设置了之后,全部设备上的 viewport 都为 375了。
            })();

注意这里也须要将最大和最小缩放比设置为和初始的值同样,否则若是它们都仍是 1 的话,前面的就没有效果了,由于如今仍是规定最大最小的缩放比为 1。

缺点:由于如今在任何设备上的viewport的宽度都为固定的宽度,例如 375 的图片放到 大屏幕上,由于宽度是固定的,因此确定会变得模糊

DPR 缩放适配

根据dpr的值,把视口进行缩放,缩放到物理像素,也就是把css像素的值设置成物理像素,让全部的设备都变成一个css像素对应一个设备像素,方便切图

(function(){
                /*
                    375*2    750 
                    320*2    640

                    375/?=750    => 375/750=2
                    1/dpr // 公式

                    320/scale=640    =>     scale=320/640    1/2
                 */

                var meta=document.querySelector('meta[name="viewport"]');
                var scale=1/window.devicePixelRatio;

                if(!meta){
                    //这个条件成立说明用户没有写meta标签,我须要建立一个
                    meta=document.createElement('meta');
                    meta.name='viewport';
                    meta.content='width=device-width,initial-scale='+scale+',user-scalable=no,minimum-scale='+scale+',maximum-scale='+scale+'';
                    document.head.appendChild(meta);
                }else{
                    meta.setAttribute('content','width=device-width,initial-scale='+scale+',user-scalable=no,minimum-scale='+scale+',maximum-scale='+scale+'');
                }
            })();

rem 适配

rem 是相对于根节点(html)的字体大小。

它的原理是把全部的设备都分红相同的若干份,再计算元素宽度所占的份数,开发的时候只须要使用一个特定的设备 而且使用rem 那么在其余设备上会自动出现相同的效果即自动适配(很神奇),而且设计稿须要以物理像素为准来设计 例如分辨率宽为 375 drp为2,那么实际针对该机型的设计搞应该为750。

媒体查询方式

即经过媒体查询,对全部范围内的尺寸给定一个 html 根结点字体大小。可参考苏宁易购。

js简单方式

  1. 计算出每一列的宽度:viewport宽度(css像素)/16(列数),并将其设置为根结点字体大小。
  2. 根据设计稿量出的实际尺寸除以 dpr,而后再根据换算后的尺寸,除以一列的宽度(1rem),元素占 n 列
  3. 而后设置元素的宽度为 nrem。
(function(){
                var html=document.documentElement;    //html
                var width=html.clientWidth;        //css像素
                // 方式一
                html.style.fontSize=width/16+'px';    //把屏幕分红了16列,以iphone为例得出一个列的值为整数
                // 方式二
                html.style.fontSize= 16 * clientWidth / 375 + 'px'; // 以iphone6 为基准,当大于 iphone6 的尺寸时,字体大小大于 16px, 同理小于时,字体小于 16px。
            })();

js经典方式

相比于上面的普通方式,经典方式省掉了,根据设计稿量出的实际尺寸除以 dpr 这一步,直接将设计稿当中量出来的尺寸除以 100 而后单位为 rem。下面依然以 iphone6 为例。

(function(doc, win, designWidth) {
                const html = doc.documentElement;
                const refreshRem = () => {
                    const clientWidth = html.clientWidth;
                    if (clientWidth >= designWidth) { //给宽度一个最大值,若是设备的宽度已经超过设计稿的尺寸了,统一按一个值去算(传的第三个参数)
                        html.style.fontSize = '100px';
                    } else {
                        html.style.fontSize = 100 * (clientWidth / designWidth) + 'px'; // 这种方式是咱们在切图的时候不须要手动去除dpr, 已经帮咱们处理好来,可是咱们在计算的时候仍是必须使用1rem = 100px来计算
                    }
                };
                
                //dom加载完的一个事件
                doc.addEventListener('DOMContentLoaded', refreshRem);
            })(document, window, 750);

vw 适配

vw 将页面分为 100 份,相关单位以下:

  1. vw Viewport's width的简写,1vw等于视口宽度的1%
  2. vh Viewport's height的简写,1vh等于视口高度的1%
  3. vmin 取vw和vh中最小的值
  4. vmax 取vw和vh中最大的值

兼容性以下:

  • >=ios 8
  • >=Android 4.4

而且 vw、vh分别表明水平和竖直方向,和横竖屏没有关系,会自动根据横竖屏来计算获得每一份的宽度,如图:

图片描述

有两种使用 vw 方式

方式一

通篇使用 vw, 和前面 rem 部分提到的 js 简单部分差很少,只不过省略了计算每一份的过程,浏览器自动帮咱们计算 1vw 是多少。注意切图的使用仍是要除以 dpr。能够采用 scss 等 css 预处理语言来简化这个过程。

方式二

经过 vw 设置根节点字体大小,页面里的尺寸依然使用rem。可是前提是你要知道页面当中根节点的字体大小,根节点字体的大小的计算参考前面 rem 布局部分的 js 经典方式

移动端存在的几个问题

固定定位

在 ios 下面,若是页面里有一个固定定位(fixed)的元素以及一个 input 元素的时候,用户但凡点击input调出键盘的时候,固定定位元素就会不起做用。解决方式:

  1. 将须要滚动的元素放到一个容器里面,容器超出就滚动,这样容器和固定定位元素就会在一个页面,就算失效了,也在一个页面内可见。

1px 问题

在移动端 dpr, 每每是 2 及其以上,因此 1px 每每表明多个物理像素,这就是 1px 问题, 解决办法:

  1. dpr 缩放适配不存在这个问题,由于 dpr 缩放适配是 1px = 1pt
  2. 可使用 css3 提供的 scale 来缩放边框为 0.5 倍, 下面是建立了一个伪类,并缩放它的边框来达到缩放的目的.
section::after{
                content: '';
                position: absolute;
                left: 0;
                top: 0;
                border: 1px solid #000;
                box-sizing: border-box;
                width: 100%;
                height: 100%;
                transform-origin: 0 0;
                transform: scale(0.5);
            }
相关文章
相关标签/搜索