细数移动端布局你不知道的那些事

2,237 阅读10分钟

前提回顾

  • 1.导言:移动端布局的写法不能向PC端布局写法一样。
  • 2.移动端在没有做任何的适配、添加额外的代码的情况下,直接去打开移动端后会发现宽度默认是980px

必知点一:英寸的概念

一般我们都用英寸来描述设备的物理尺寸

>>>
例如我们说一个手机6.5英寸屏幕
其实指的就是对角线的距离

1英寸 = 2.54 厘米 

必知点二:屏幕分辨率/物理像素

屏幕具体由多少个像素组成,
并不是分辨率高,就说明屏幕清晰的,
还需要考虑尺寸问题。

必知点三:像素

一个小正方形的方块,每一个像素都具备颜色和特定的位置。
像素并不是一个绝对单位
像素是一个比例单位

必知点四:像素点和清晰度的关系(pixel per inch)

ppi:
每英寸包含的像素点。
根据ppi可以判断出哪个屏幕清晰度更高
分辨率x/y就对应着水平像素点数和垂直像素点数

ppi的计算公式为:

  • 2.导言引入:在pc端绘制一个宽高为200px的div块转为手机移动端后经测量宽高为77px,而我们想要的结果是在手机移动端测量也应该为200px

必知点五:设备独立像素

每个设备都有属于自己的独立像素,
通过浏览器的模拟器,
我们可以看到,每个设备的独立像素。

必知点六:设备像素比

像素比:物理像素/分辨率 和 设备独立像素的比值。

例如iphone6的物理像素/分辨率为750*1334,
设备独立像素为375*667,
所以其像素比为2

当然也有设备例外
  • 3.导言引入:在pc端写一个宽高都为300px的div块,在移动端iphone6下经测量宽高都为114px,这是怎么自动换算的呢?需要用到设备独立像素和布局视口??
iphone6的设备独立像素为375*667
它的布局视口为980
所以根据计算 375/980 *300 =114
得出在移动端的宽高为114px

注意!!! 浏览器页面一定不能有缩放,要是 100% 

必知点七:视口概念

- 7.1布局视口

布局视口:
是网页布局的基准窗口,在这里只考虑布局,
也就是不会有非布局的内容,
不会包含滚动条,菜单栏。

在 js 中可以通过
`document.documentElement.clientWidth`
来获取布局视口大小

移动端布局视口的大小不受滚动条的影响,
滚动条像是浮起来了

- 7.2视觉视口

视觉视口:
用户视觉上看到的真实区域,包括滚动条。

在 js 中可以通过`window.innerWidth`来获取

- 7.3理想视口

当布局视口和视口一致的时候,那结果就是写的css像素和呈现出来的像素是一样的了

在 js 中利用`window.screen.width`可以获取到
  • 4.导言引入:

页面上呈现的宽度= 设备独立像素/布局视口 * 元素宽度。

device-width为设备独立像素

以iphone6为例其device-width为375*667

width为布局视口的宽度

width=device-width即 1*元素宽度=页面上呈现的宽度

必知点八:通过meta标签的viewport进行适配

viewport相关配置

属性                    值                          描述
width             正整数或device-width      以像素为单位,定义布局视口的宽度


height           正整数或device-width      以像素为单位,定义布局视口的高度


initial-scale     允许是小数               定义页面初始缩放比例


minimum-scale     0.0 - 10.0              定义缩放的最小值


maximum-scale     允许是小数              定义缩放的最大值(ios10&ios10+无效)


user-scalable       yes / no             设置是否允许缩放,同上无效
initial-scale = 设备独立像素 / 视觉视口宽度

视觉视口宽度 = 设备独立像素 / initial-scale
注意事项
1. ios10 及 ios10+ 设置最大缩放值无效
2. initial 和 width 是有冲突的
3. initial 和 最小值 是一致的
4. 部分安卓机型,不接受width = 具体数值 这样的操作
通用设置:

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

必知点九:直接根据像素比进行适配

以iphone6为例

html的页面代码

div{
	width:600px;
	height:600px
}

这样可以在移动端中手机模拟器中
显示宽高为300pxdiv块
麻烦!!!!!
js的逻辑代码:
<script>
    var meta = document.createElement('meta');
    var scale = 1 / window.devicePixelRatio;
    meta.name = "viewport";
    meta.content="initial-scale="+ scale +",minimum-scale="+ scale+",maximum-scale="+ scale+",user-scalable=no";
    document.head.appendChild(meta);
</script>
在不同的手机型号下之前设置的css像素无法继续满足需求

必知点十:rem适配

rem -> root em 其实翻译过来就是根据 根节点<html></html>计算em

<style>
    html{
        font-size: 20px;
    }
    div{
        font-size: 15px;
        width: 5em;
        height: 5em;
        background: rebeccapurple;
    }
</style>

此时的width=20*5=100px
  • 10.1 通过js动态的设定font-size
<script>
    var html = document.documentElement;
    var widths = html.clientWidth; //获取布局视口
	//在移动端clientWidth就是设备独立像素
	//例如iphone6的html.clientWidth为375
    var num = 10; //类比栅格布局
    html.style.fontSize = widths / num + 'px'; 
</script>
  • 核心思想:需要确定我要把屏幕划分为几份,这里是划分为10份,以iphone6为例,在获取布局视口(设备独立像素)375px后,可以算出一份是37.5px,也就是我们通过js动态的把html的font-size设置为了37.5px,然后如果我想要呈现出一个宽为300px的div块,我只需要写成300/37.5rem即可,这里的计算可以交由less、sass来帮我们处理,通过一个变量记住这个37.5
//less文件


body {
    margin: 0;
}


//加上rem只是为了让除完之后带上rem单位而已
//这里的37.5的意思是 一份是37.5的距离
//这里只是代表的是份数的关系
@rem: 37.5rem;



.box {
    width: 186/@rem;
    height: 200/@rem;
    background: #0a8cd2;
}

必知点十一:vw/vh

不管设备是横屏还是竖屏,

vw指的都是水平方向的,

vh指的都是垂直方向的。

它和设置单位百分比不一样,

不会受到父级宽度的影响,

这样我们通过css就可以获取到当前的视口宽度了,

利用**获取到的视口宽度 / 100vw **

以iphone6为例,其设备独立像素为375*667


html{
    font-size: 10vw; //37.5px
}
/* 
因为整个屏幕是 100vw ,
这里我们分成 10 个格子,
一个格子是 10vw 的 font-size
*/
div{
    width:5rem; 
    height:5rem;
}
div{
    width:50vw; //一半
    height:50vw;
}

必知点十二:横竖屏适配

  • 12.1通过CSS媒体查询实现的做法
@media screen and (orientation:portrait){
    #box{
        background: red;
    }
}
@media screen and (orientation:landscape){
    #box{
        background: green;
    }
}
  • 12.2 通过CSS设置安全区

以ios设备为例

利用iphoneX专属样式viewport-fit属性,他会对网页设置安全区

<meta name="viewport" content="viewport-fit=cover>

body{
    padding-bottom:constant(safe-area-inset-bottom);
    padding-bottom:env(safe-area-inset-bottom);
}

---constant:小于IOS11.2版本生效
---env:大于IOS11.2版本生效
---safe-area-inset-lef 设置左侧安全区
---safe-area-inset-right 设置右侧安全区
---safe-area-inset-top 设置顶部安全区
---safe-area-inset-bottom 设置底部安全区

必知点十三:1px适配方案

这里运用的是缩放transform:rotate()方案

基本思路:

设置一个专门的class来处理1px的问题,利用伪类给其添加

.border_1px:before{
    content: '';
    position: absolute;
    top: 0;
    height: 1px;
    width: 100%;
    background-color: #000;
    transform-origin: 0% 0%; //以左上角为原点进行缩放---十分关键
}
@media only screen and (-webkit-min-device-pixel-ratio:2){
    .border_1px:before{
        transform: scaleY(0.5);
    }
}
@media only screen and (-webkit-min-device-pixel-ratio:3){
    .border_1px:before{
        transform: scaleY(0.33);
    }
}


-webkit-min-device-pixel-ratio 获取像素比

transform: scaleY(0.5) 垂直方向缩放,后面的数字是倍数

必知点十四:图片模糊问题

基本思路:

根据不一样的像素比,准备不一样的图片,

正常来说是1px图片像素 对应1px物理像素

.avatar{
    background-image: url(conardLi_1x.png);
}
@media only screen and (-webkit-min-device-pixel-ratio:2){
    .avatar{
        background-image: url(conardLi_2x.png);
    }
}
@media only screen and (-webkit-min-device-pixel-ratio:3){
    .avatar{
        background-image: url(conardLi_3x.png);
    }
}

必知点十五:滚动穿透问题

基本思路:

给body添加position:fixed

就可以使滚动条失效,

这里弹框的显示和隐藏,

我们利用JS进行控制,

而且添加上position:fixed的一瞬间,

可以看到页面一下回到0,0的位置,

因为fixed是根据可视区定位的。

<script>
  var btn=document.querySelector('#btn');
  var alerta=document.querySelector('#alerta');
  var txt=document.querySelector('#txt');
  btn.onclick=function(){
      alerta.style.display='block'
      txt.style.position='fixed';
      //txt.style.position='static';
  }
</script>

必知点十六:键盘唤起问题

问题重现:

当底部根据页面进行fixed定位的时候,

键盘弹出一瞬间,fixed会失效,

解决方案: 滚动内容的定位变成类似absoulte

main的内容无滚动,

就不会连带fixed一起动了

保证移动端滑屏顺滑可以加上的CSS样式
-webkit-overflow-scrolling: touch;

必知点十七:移动端的一些神奇操作

  • 17.1 移动端手机号码识别
<meta name="format-detection" content="telephone=no" />


safari会对一些可能是手机号码的数字,
进行识别,
我们可以利用上面的方式,禁止识别
  • 17.2 手动开启拨打电话功能
<a href="tel:13300000000">110</a>
  • 17.3 手动开启短信功能
<a href="sms:10086">13300000000</a>

在手机上点击这个链接,
可以跳转去短信页面,
给该手机号发送消息
  • 17.4 移动端邮箱识别
<meta name="format-detection" content="email=no" /> 
  • 17.5 手动开启邮箱发送功能
<a href="mailto:444000@qq.com">发送邮件</a>

调用邮箱发送功能
  • 17.6 优先启用最新版本IE和chrome
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> 
  • 17.7 设置添加到主屏幕后的标题
<meta name="apple-mobile-web-app-title" content="你好啊"> 

  • 17.8 设置添加到主屏后的APP图标
<link href="short_cut_114x114.png" rel="apple-touch-icon-precomposed">

  • 17.9 设置启动启用webApp全屏模式
<meta name="apple-mobile-web-app-capable" content="yes" /> 
<meta name="apple-touch-fullscreen" content="yes" /> 

---apple-mobile-web-app-capable
删除默认的苹果工具栏和菜单栏,默认为no

---apple-touch-fullscreen
全屏显示

必知点十八:移动端默认样式

18.1 移动端默认字体

  • 数字 和 英文字体 可使用Helvetica 字体,IOS 和 Android都有这个字体

  • 手机系统都有自己默认的字体,直接使用默认的

body{
    font-family:Helvetica;
}

18.2 IOS系统中,链接、按钮等点击时会出现有灰色遮罩

a,button,input,textarea{-webkit-tap-highlight-color: rgba(0,0,0,0)}

18.3 去除圆角

button,input{
    -webkit-appearance:none; //去除ios设备圆角
    border-radius: 0;
}

18.4 禁止文本缩放

html{
     -webkit-text-size-adjust: 100%;
}

必知点十九:拓展学习

1.变化原点

transform-origin 变化原点
----关键词`left`、`right`、`top`、`bottom`
  - --数值(px)
  - --默认 center center

2.scss语法

2.1自设定一个转换为rem单位的函数方法
@function rem($num){
	@return ($num/75) *1rem
}

.left{
	width:rem(200)
}

2.2定义一个公共变量
$rem:75
.left{
	200rem/$rem
}


2.3抽离一个公用的混入样式
@mixin clear{
	&:after{
		content:'';
		height:0;
		display:block;
		clear:both;
	}
}

.course{
	@include clear;
	&_item{
		float:left
	}
}

代码解析为===>
.course:after{
	content:'';
		height:0;
		display:block;
		clear:both;
}

.course_item{
	float:left
}


2.4 混入和引入

错误写法:(/斜杠会执行除法运算)
@mixin font($size,$height,$color){
	font:$size/$height '微软雅黑';
	color:$color
}

改进--不让/被当作除法运算
@mixin font($size,$height,$color:#333){
	font:$size#{'/'}$height '微软雅黑';
	color:$color
}

使用方法:
.box{
	font(24px,40px,#fff)
}	


3 photoshop的基操

3.1切片工具的使用
配合切片工具和psd文件可以将需要的图片导出为
web所用格式(快捷键为ctrl+shift+alt+s)
并在存储中设置切片为所有用户切片
如果要清除所有切片可在菜单栏中的视图选项中
找到清除所有切片

3.2 利用阿里巴巴矢量库将svg格式图片转为字体图标

ps中可导出图片为svg的格式图片(快捷键:ctrl+shift+alt+w)


3.3 利用钢笔工具来制作矢量图形
在菜单栏里选择 ‘形状’ 利用钢笔工具
描边绘制出形状后选择相应的所有图层
右键点击合并形状后导出为svg格式图片

4.background的简写速记

background:#fff url('./img/img.png') no-repeat 0 0/100%

分别对应着:
background-color background-image background-repeat background-position/background-size

5.利用伪类before实现内容块垂直居中

html页面代码为:
<div class="box1">
    <span>我要垂直居中我要垂直居中我要垂直居中我要垂直居中我要垂直居中我要垂直居中我要垂直居中我要垂直居中我要垂直居中我要垂直居中</span>
</div>


style样式页面代码为:
.box1{
    font-size: 16px;
    width: 1000px;
    height: 500px;
    border: 1px solid black;
    font-size:0
    
    span{
        vertical-align: middle;
        word-break: break-all;
        display: inline-block;
        font-size:14px
    }

    &:before{
        content: '';
        width: 10px;
        height: 100%;
        display: inline-block;
        vertical-align: middle;
        background-color: pink;
    }
}   

6.bodyhtml的高度默认是0
7.input默认有borderoutlinebackground
8.background:linear-gradient(to right bottom,#000,fff)
9.背景颜色和背景图片是不会冲突的