最近一直在做移动端的页面,发现很多的坑,这里做一下总结,填填坑……
IOS的机子,默认英文输入法状态下,首字母是自动大写的,有时候挺烦人的。
在iOS中,默认情况下键盘是开启首字母大写的功能的,如果业务不想出现首字母大写,可以这样:
<input type="text" autocapitalize="off" />
在iOS上,输入框默认有内部阴影,但无法使用 box-shadow 来清除,如果不需要阴影,可以这样关闭,不过加了上面的属性后,iOS下默认还是带有圆角的,不过可以使用 border-radius属性修改:
input, textarea { border: 0; -webkit-appearance: none; }
去除input[type=number]的默认样式
input[type=number] { -moz-appearance:textfield; } input[type=number]::-webkit-inner-spin-button, input[type=number]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
通常,移动端如果我们不设置line-height值时,大部分机器输入框的光标是可以居中的,但是如果我们用line-height:$height值,却导致光标不居中问题
遇到这个问题,我们只能用line-height:$height\9来处理居中问题,这里就不能用line-height:$height,示例代码:
height:40px; line-height:40px\9; font-size:16px;
css中text-indent缩进,但是在部分andriod机中,光标是输入框先获得光标依然在最左边,然后输入文字才到缩进的值,这样很不好,建议通过padding-left设置缩进,完美解决。
在做移动端页面时,会发现所有a标签在触发点击时或者所有设置了伪类 :active 的元素,默认都会在激活状态时,显示高亮框,如果不想要这个高亮,那么你可以通过css以下方法来禁止:
.xxx { -webkit-tap-highlight-color: rgba(0, 0, 0, 0); }
这个设置,在大部分机子上都是起效果的。但是,移动端三星自带浏览器,点击页面任意a标签时,设置-webkit-tap-highlight-color:rgba(0,0,0,0)还是会有阴影底色,这应该是浏览器强制加上去的,通过代码设置也无法覆盖。
有一种妥协的方法是把页面非真实跳转链接的a标签换成其它标签,可以解决这个问题。
建议大家写在使用border-radius写圆角时,还是不要border-radius:50%实现圆,建议用具体的数值。
移动端 当设置 通用viewport 后。代码中的 1px 单位的边框实际在高清屏( @2x )pixel-ratio:2上显示的是2像素,pc ( 非高清屏幕 ) 上显示的正常的1px。
border:1px solid #000
可能看到这里,大家又有疑问了,干嘛我们不把border-width:0.5px呢,可是早的浏览器不支持,到了ios8.0才支持这个。
现在通常来说有两种解决方案:1.通过border-image实现(但缺点是不能实现四边边框,而且加载浪费资源) 2.通过scale进行缩放
1.border-image 实现演示(扫码地址):
2.通过scale进行缩放
①单边1像素边框处理方法通过伪类画出边框,然后通过scale将其缩放,最后处理@1.5x(安卓机器) @2.0x(ios机器) @3.0x(注意是 1080p)的缩放比例
%border-btm-1pt{ content: ''; height: 0px; display: block; border-bottom:1px solid #ddd; position: absolute; left:0; right:0; bottom:0; } .some_div{ position:relative; // 因为伪类用的absolute 所以需要添加 relative &:after{ @extend %border-btm-1pt border-color:#f09; // 在这里自定义边框颜色。 } } //适配早期的andriod机器 1/1.5 = 0.666 @media only screen and (-webkit-min-device-pixel-ratio: 1.5) { .some_div{ -webkit-transform: scaleY(0.666) } } //高清屏( @2x ) iphone这种 1/2 = 0.5 @media only screen and (-webkit-min-device-pixel-ratio: 2) { .some_div{ -webkit-transform: scaleY(0.5) } } //1080机子@3x @media only screen and (-webkit-min-device-pixel-ratio: 3) { .some_div{ -webkit-transform: scaleY(0.333) } }
②处理四边边框1px问题,两种思路:1.子边框两边通过伪类,父边框两边通过伪类 2.一个伪类,画出四边边框,然后通过width:200%;height:200%(这里主要说的是@2.0x机器,由于@1.5 @3比例无法算整会导致不够精确,不予讨论);即把内容缩放两倍,进行缩放scale ,处理。
这里举例第二种情况(但是这里要注意的是,如果容器里面有a链接,就会导致设置的伪类遮住元素,无法点击,所以容器里面的内容也要设置绝对定位):
<style type="text/css"> h3{text-align:center} div.border_scale{ margin:100px auto; width:600px; height:150px; position:relative; } div.border_scale:before{ display:block; position:absolute; content:"\20"; width:200%; height:200%; border:1px solid #000; -webkit-transform-origin:0 0; transform-origin:0 0; -webkit-transform:scale(0.5); transform:scale(0.5); top:-1px; left:-1px; } div.border_scale a{ display:block; width:100%; height:100%; text-align:center; } </style>
<h3>border的1像素框 scale</h3> <div class="border_scale"> <a href="http://www.baidu.com">百度</a> </div>
在制作H5页面我们难免会对一些元素进行旋转、变形,可是这样却恶来许多麻烦,出现锯齿他妈的咋办,还不如直接图片,对吧。
我们可以通过这样直接解决烦恼:我发现呢微信更新到6.2.4之后对旋转锯齿有些修复
-webkit-transform: rotate(-4deg) skew(10deg) translateZ(0); transform: rotate(-4deg) skew(10deg) translateZ(0); outline: 1px solid rgba(255,255,255,0)
在我们做h5页面时,经常遇到要在容器内容里面做滚动调的问题,但是,当我们用那些滚动条时,发现,在andriod里面实在是太丑陋了,通常还会出问题,产品MM也接受不了,所以这里给大家提供一个解决方案:
.scroll::-webkit-scrollbar{width:5px; height:5px;} .scroll::-webkit-scrollbar-button{width:0;height:0;} .scroll::-webkit-scrollbar-corner{display:block; } .scroll::-webkit-scrollbar-thumb{background-clip:padding-box;background-color:rgba(0,0,0,.2);border-radius:8px;}//还可以设置滚动条的颜色 .scroll::-webkit-scrollbar-thumb:hover{background-clip:padding-box;background-color:rgba(0,0,0,.5);border-radius:8px;}
让我们的滚动条变成这样,从此妈妈再也不用担心滚动条问题了,上图:
steps() 第一个参数 number 为指定的间隔数,即把动画分为 n 步阶段性展示,第二个参数默认为 end,设置最后一步的状态,start 为结束时的状态,end 为开始时的状态。
steps 有两个参数 第一个肯定是分几步执行完 第二个有两个值 start 第一帧是第一步动画结束 //第一个阶段结束之后的值 end 第一帧是第一步动画开始 //第一个阶段开始的值
理解 start 第一帧是第一步动画结束 end 第一帧是第一步动画开始,number为阶段数
demo:http://pingfan1990.sinaapp.com/honor7/anim.html
我们看最后一个tab,可以反衬出以下
steps()
第一个参数将动画分割成三段。当指定跃点为 start
时,动画在每个计时周期的起点发生阶跃(即图中空心圆 → 实心圆)。由于第一次阶跃发生在第一个计时周期的起点处(0s),所以我们看到的第一步动画(初态)就为 1/3 的状态,因此在视觉上动画的过程为 1/3 → 2/3 → 1 。
当指定跃点为 end,动画则在每个计时周期的终点发生阶跃(即图中空心圆 → 实心圆)。由于第一次阶跃发生在第一个计时周期结束时(1s),所以我们看到的初态为 0% 的状态;而在整个动画周期完成处(3s),虽然发生阶跃跳到了 100% 的状态,但同时动画结束,所以 100% 的状态不可视。因此在视觉上动画的过程为 0 → 1/3 → 2/3(回忆一下数电里的异步清零,当所有输出端都为高电平的时候触发清零,所以全为高电平是暂态)。
但是当我们看到这样的图片的时候,知道这个有12帧,我么就会理解为steps(12),其实这里是11个阶段完成的,应该是steps(11);
demo:http://pingfan1990.sinaapp.com/honor7/anim1.html
steps(11)帧等价于,总长1680,默认是steps(11,end):
@-webkit-keyframes run1{ 0%{ background-position: 0 0; } 9.09%{ background-position: -140px 0; } 18.18%{ background-position: -280px 0; } 27.27%{ background-position: -420px 0; } 36.36%{ background-position: -560px 0; } 45.45%{ background-position: -700px 0; } 54.54%{ background-position: -840px 0; } 58.33% { background-position: -980px 0; } 63.63% { background-position: -1120px 0; } 72.72% { background-position: -1260px 0; } 81.81% { background-position: -1400px 0; } /*中间缺10张图,11个阶段*/ 100% { background-position: -1540px 0; // 12帧 } }
而steps(12)帧等价于,总长1680,默认是steps(12,end):
//这里background-position-x按帧均分,我就不算了 @keyframes run { 0% { background-position: 0 0; } 8.33% { background-position: -140px 0; } 16.67% { background-position: -280px 0; } 25% { background-position: -420px 0; } 33.33% { background-position: -560px 0; } 41.67% { background-position: -700px 0; } 50% { background-position: -840px 0; } 58.33% { background-position: -980px 0; } 66.67% { background-position: -1120px 0; } 75% { background-position: -1260px 0; } 83.33% { background-position: -1400px 0; } 91.67% { background-position: -1540px 0; } 100% { background-position: -1540px 0; } }
做动画时请不要在:before和:after这些伪类身上做动画,移动端不支持。做animation动画时,我们可以结合,webkitAnimationEnd 这个事件来监听,改变动画,做出更炫的效果。
click300ms延迟是由于iphone采用的是双击默认是放大页面,实现click是判断第二次点击间隔时间300ms认定为click,许多厂家沿用而导致的,click 事件因为要等待双击确认,会有 300ms 的延迟,体验并不是很好。
开发者大多数会使用封装的 tap 事件来代替click 事件,所谓的 tap 事件由 touchstart 事件 + touchmove 判断 + touchend 事件封装组成。
FastClick.js和tap.js可以有效的解决300ms延迟的问题。
参考资料 单击300ms延迟
简单的说,由于在移动端我们经常会使用tap(touchstart)事件来替换掉click事件,那么就会有一种场景是:
<div id="mengceng"></div> <a href="www.jd.com">www.jd.com</a>
div是绝对定位的蒙层z-index高于a,而a标签是页面中的一个链接,我们给div绑定tap事件:
$('#mengceng').on('tap',function(){ $('#mengceng').hide(); });
我们点击蒙层时 div正常消失,但是当我们在a标签上点击蒙层时,发现a链接被触发,这就是所谓的点透事件。
分析原因:
touchstart 早于 touchend 早于 click。亦即click的触发是有延迟的,这个时间大概在300ms左右,也就是说我们tap触发之后蒙层隐藏,此时click还没有触发,300ms之后由于蒙层隐藏,我们的click触发到了下面的a链接上。
解决办法:
1 尽量都使用touch事件来替换click事件。
2 阻止a链接的click的preventDefault
移动端touch事件:
touchstart //当手指接触屏幕时触发
touchmove //当已经接触屏幕的手指开始移动后触发
touchend //当手指离开屏幕时触发
touchcancel//当某种touch事件非正常结束时触发
这4个事件的触发顺序为:
touchstart -> touchmove -> touchend ->touchcancel
对于某些android系统touch的bug:
比如手指在屏幕由上向下拖动页面时,理论上是会触发 一个 touchstart ,很多次 touchmove ,和最终的 touchend ,可是在android 4.0上,touchmove只被触发一次,触发时间和touchstart 差不多,而touchend直接没有被触发。这是一个非常严重的bug,在google Issue已有不少人提出 ,这个很蛋疼的bug是在模拟下拉刷新是遇到的尤其当touchmove的dom节点数量变多时比出现,当时解决办法就是用settimeout来稀释touchmove。
或者通过在touchmove阻止默认行为preventDefault,这里就会导致要通过js来实现页面的滚动:
//发现在android4.0以上的webkit浏览器touchmove事件只触发一次,加event . preventDefault()就可以,但是这里就导致只能通过js来实现页面的滚动 addEventListener("touchmove",function(e){ e.stopDefault(e); },false)
这个不是什么问题,我只是觉得好,所以说一下,当回搬运工,简单的摇一摇案例。
if (window.DeviceMotionEvent) { window.addEventListener('devicemotion',deviceMotionHandler, false); } var speed = 30;//speed var x = y = z = lastX = lastY = lastZ = 0; function deviceMotionHandler(eventData) { var acceleration =event.accelerationIncludingGravity; x = acceleration.x; y = acceleration.y; z = acceleration.z; if(Math.abs(x-lastX) > speed || Math.abs(y-lastY) > speed || Math.abs(z-lastZ) > speed) { //简单的摇一摇触发代码 alert(1); } lastX = x; lastY = y; lastZ = z; }
关于deviceMotionEvent是HTML5新增的事件,用来检测手机重力感应效果具体可参考:
http://w3c.github.io/deviceorientation/spec-source-orientation.html
经典材料:
meta标签大全 http://segmentfault.com/blog/ciaocc/1190000002407912
使用border-image实现类似iOS7的1px底边:https://github.com/AlloyTeam/Mars/blob/master/solutions/border-1px.md
devicePixelRatio:http://imququ.com/post/devicepixelratio-and-border-width.html
移动问题小结:http://www.alloyteam.com/2015/06/yi-dong-web-wen-ti-xiao-jie/