初识移动WEB

2016/11/17 移动端CSS

这个非常实用,重要的是实用meta标签和rem单位。

在接下来的时间,我尽量把之前的代码进行移动适配。

# 基础知识

开发过程中,原本PC端可以正常显示的界面在移动端变得乱七八糟,这罪魁祸首就是这些没有统一的概念。

# 像素 pixels

# 第一组概念

计算公式:px = ( dpr )² X dp

  • px:css pixels 逻辑像素,抽象单位,这是开发中常用的像素单位。
  • dp,pt:device independent pixels 设备无关像素。
  • dpr:devicePixelRatio 设备像素缩放比。

不同设备的dpr不一定相同(iPhone5的dpr=2)。

# 第二组概念

  • DPI:打印机每英寸可以喷的墨汁点
  • PPI:屏幕每英寸的像素数量,即单位英寸内的像素密度

这两个概念很容易理解,做好区分即可。

# 视窗 viewport

由于移动端浏览器存在两套viewport(度量viewport、布局viewport),而我们的部分css代码用到了页面宽度(margin:0 auto;),所以会出现一些问题,最常见的就是原本居中的页面,在移动端浏览不居中了。

# meta标签

<meta name = "viewport" content = "name = value,name = value">,标签中的name,value可以有一下各种选择:

  1. width:设置布局viewport的特定值
  2. initial-scale:设置页面的初始缩放
  3. minimum-scale:最少缩放
  4. maximum-scale:最大缩放
  5. user-scalable:用户能否缩放

我们通过以上的选项,来控制达到想要的效果。

# viewport设置

<meta name = "viewport" content = "width=???">,这个是最简便的解决方法,原理是通过设置移动端的视窗宽度来解决视窗宽度与设备宽度不一致的情况。其中,width值可以console得到。

document.body.clientHeight;
window.innerWidth;
1
2

据此,我们得出最佳的viewport设置:【布局 viewport】=【设备宽度】=【度量 viewport】 <meta name = "viewport" content = "width=device-width,initial-scale=1,user-scalable=no"> 效果是,固定移动端的页面大小,需要为其设置独立的一套css。

# 设计方案

方案一:根据设备的实际宽度来设计(常用) 使用【布局 viewport】=【设备宽度】=【度量 viewport】的思想,需要对移动端重新写一套样式。

方案二:1px = 1dp 缩放0.5。根据设备的物理像素dp等于抽象像素px来设计。此时1像素边框和高清图片都不需处理。

# 高效的移动WEB布局

# Flexbox弹性盒子布局

/*在父元素的样式中写*/
display: -webkit-flex;   /*表示要显示为弹性盒子布局*/ 
/*在子元素的样式中写*/
flex: 1;   /*表示所占布局的份数*/
1
2
3
4

由此引发多种可能:

  1. 等比划分:子元素均不写宽度,都是用flex表示比例
  2. 混合划分:子元素可以有固定宽度,剩余的部分按比例划分

# Tips

不定宽高的水平垂直居中

/*第一种解决办法*/
.box{
 position: absolute;
    top: 50%;
    left: 50%;
    z-index: 3;
    -webkit-transform: translate(-50%,-50%);
 background: #eee;    
}
/*第二种,flexbox版*/
.box{
 justify-content: center;
    align-items: center;
    display: -webkit-flex;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# Flex弹性盒模型

父元素的属性

【 flex-direction 】

flex-direction: row; /*默认,按列排*/
flex-direction: row-reverse; /*按列反序排*/

flex-direction: column;    /*按行排*/
flex-direction: column;    /*按行反序排*/
1
2
3
4
5

【 flex-wrap 】

-webkit-flex-wrap: nowarp;    /*默认,子元素不换行*/
-webkit-flex-wrap: warp;    /*子元素换行*/
-webkit-flex-wrap: warp-reverse;    /*子元素换行,反序排列*/
1
2
3

【 justify-content 】

justify-content: flex-start;    /*默认,靠左排*/
justify-content: flex-end;    /*靠右排*/
justify-content: flex-center;    /*居中排列*/
justify-content: space-between;    /*靠两边排列*/
justify-content: space-around;    /*元素等分,居中*/
1
2
3
4
5

【 align-items 】

align-items: flex-start;    /*垂直方向靠上*/
align-items: flex-end;    /*垂直方向靠下*/
align-items: center;    /*垂直方向居中*/
align-items: auto;    /*垂直方向填满容器*/
align-items: baseline;    /*垂直方向靠字体下边缘*/
align-items: stretch;    /*垂直方向填充*/
1
2
3
4
5
6

子元素的属性

【 align-self 】

align-self: flex-start;    /*垂直方向靠上*/
align-self: flex-end;    /*垂直方向靠下*/
align-self: center;    /*垂直方向居中*/
align-self: auto;    /*垂直方向填满容器*/
align-self: baseline;    /*垂直方向靠字体下边缘*/
align-self: stretch;    /*垂直方向填充*/
1
2
3
4
5
6

# 兼容性

  • IOS 兼容最新的flex布局
  • Android4.4 以下,只兼容旧版的flexbox布局
  • Android4.4 以上,兼容最新的flex布局

# 响应式设计

@media screen and (max-width:1024px){
 #wrap{
     width: 95.5%;
    }
}
1
2
3
4
5

解决思路:通过媒体查询写不同情况下的响应式代码,百分比布局。

设计点一:百分比布局,可以有平滑的过渡。

设计点二:弹性图片,max-width: 100%

设计点三:重新布局,舍弃与保留。

# 样式处理

# 高清图片

使用更高分辨率的图片,在retina屏幕上就能显示清晰。

原理是dpr != 1;

# 一像素边框

1px的边框是用2dp渲染,导致不清晰。

一般使用缩放的方式解决(sacleY(0.5))。

# 相对单位

em:根据父节点的font-size为相对单位

rem:根据HTML的font-size为相对单位


问题:基值应该是多少?

rem = screen.width/10

为了适应屏幕,建议在 不同屏幕下设置不同的值

/*默认320px*/
html{font-size: 32px;}
/*iphone 6*/
@media (min-device-width:375px){
 font-size: 37.5px;
}
/*iphone 6 plus*/
@media (min-device-width:414px){
 font-size: 41.4px;
}
1
2
3
4
5
6
7
8
9
10

# 多行文本溢出

/*单行文本溢出*/
.inaline{
 overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}
/*多行文本溢出*/
.intwoline{
 display: -webkit-box !important;
    overflow: hidden;
    
    text-overflow: ellipsis;
    word-break: break-all;
    
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 终端交互优化

# Tap事件

由于要判断事件状态,手机设置了click事件的300ms的延迟响应时间,所以要寻求替代的方法。

基于移动框架库Zepto.js实现tap事件。

# 问题(官方已解决)

Tap“点透”Bug,重叠部分点击时,会有穿透效果。

解决方案:

  1. 使用缓冲动画,过渡300ms的延迟
  2. 中间层dom元素的加入,让中间层承受,随后隐藏
  3. “上下”都使用tap事件,原理上解决了问题(但标签原生的click事件不可避免)
  4. 改用Fastclick库

# 触摸 touch

# 事件

touchstart:手指触摸屏幕触发

touchend:手指离开屏幕触发

touchmove:手指滑动触发

# 对象

touches:触摸操作返回的touch对象的数组

包含了以下属性:

clientX:触摸点在视窗上的X坐标

clientY:触摸点在视窗上的Y坐标

identifier:触摸的ID,唯一

pageX:触摸点在整个页面的X坐标

pageY:触摸点在整个页面的Y坐标

screenX:触摸点在屏幕中的X坐标

screenY:触摸点在屏幕中的Y坐标

target:触摸点的DOM节点

# 弹性滚动

IOS下

  1. body层,默认自带效果。
  2. 局部,body{overflow:scroll; -webkit-overflow-scrolling:touch;}

Android下

不支持原生滚动,需要借助第三方库实现,iScroll。

# 总结

移动端的使用,不仅仅是基本的浏览,而且由于交互方式发生改变,对应的事件也会发生改变。

我现在对于移动端的认识,已经超过从前,不只是@media了,还明白了事件、viewport的原理等等。

如果可以,我想把之前的“看你有多色”,改成移动端适用的。