本文档针对移动前端开发,包括 Hybrid
里面的web页面,非 Native
应用,适用于iOS6.0+
, Android4.0+
,是多年积累的经验,分享给你们。css
若是你想使用元素的伪类来实现 按下激活
状态,那么你须要知道如下问题:html
:active
都是无效;Android Browser
和 Chrome
都支持伪类 :active
,其它第三方浏览器有部分不支持;:active
而且当前浏览器环境支持,当手指在滚动或者无心间的划过期,:active
状态都会被激活;为了规避上述全部的问题,若是须要
按下激活
状态,推荐使用js
新增一个className
前端
iOS上的几乎任何浏览器输入框(input, textarea)默认有内部阴影,但没法使用 box-shadow
来清除,若是不须要阴影,能够这样关闭:web
input,
textarea {
/* 方法1: 去掉边框 */
border: 0;
/* 方法2: 边框色透明 */
border-color: transparent;
/* 方法3: 重置输入框默认外观 */
-webkit-appearance: none;
appearance: none;
}
复制代码
在 iOS
上,若是将输入框 disabled
,此时输入框内的文字颜色将比 color
所定义的要浅,而且没法经过给输入框的伪类 :disabled
定义 color
来修正。chrome
想解决这个问题,能够做以下设置,定义输入框的文本填充色:api
input:disabled {
-webkit-text-fill-color: #000;
}
复制代码
须要注意的是,在 Mac
上的 Safari
也有一样的问题。浏览器
Samsung S4
手机在 Android Browser4.4.2
上(其余版本未测),若是你使用了 border-radius
,而且使用了 -webkit-transform
属性,当使用了 translatez
或者 translate3d
值,圆角会出现问题:安全
.test {
border: 2px solid red;
width: 50px;
height: 50px;
border-radius: 50%;
background-color: gray;
box-shadow: 0 2px 5px rgba(0, 0, 0, .3);
-webkit-transform: translate(0, 0) translatez(0);
transform: translate(0, 0) translatez(0);
}
复制代码
<div class="test"></div>
复制代码
如上代码,-webkit-transform: translate(0, 0) translatez(0)
将会致使圆角没法包裹住 background-color
。性能优化
固然,-webkit-transform: translate3d(0, 0, 0)
也是同样的,因此若是你的某个场景是这样的,那么能够直接使用 -webkit-transform: translate(0, 0)
来避免这个问题。app
在红米和OPPO等手机某些版本的 Android Webview
中,若是一个元素定义了 border
+ border-radius
,这时若是该元素有背景,那么背景将会溢出圆角以外。
之因此会出现这个问题:其主要缘由是由于CSS对背景裁剪(background-clip)有不一样的处理方式,一般它能够是 border-box | padding-box | content-box
这3种方式。
浏览器的默认裁减方式是 border-box
,即溢出 border
以外的背景都将被裁减。
对于上述没法裁减边框以外背景的手机,将值定义为 padding-box | content-box
都能fix这问题,不过更推荐使用 padding-box
。由于使用 content-box
,若是定义了 padding
不为 0
,背景将没法铺满元素。
在移动平台上开发时,用CSS画一个圆很简单,只须要一句代码:
.circle {
border-radius: 50%;
}
复制代码
不过,在 Android Browser2.*
上,这个定义将会失效,而显示为默认的矩形。
由于 Android Browser2.*
不支持以 百分比
做为 border-radius
的值,因此若是你须要兼容 Android Browser2.*
,那么你能够这样:
.circle {
width: 10rem;
height: 10rem;
border-radius: 5rem;
}
复制代码
若是你以为这样定义不够灵活,想懒一点,那么其实能够给 border-radius
预设一个比较大的值,好比 100rem
,用以免当元素的尺寸变了,圆角半径也得跟着变,除非元素的尺寸超出了你预设的阀值。
有的时候你可能会为了减小页面上的DOM数,而使用伪元素。但若是你想给伪元素增长 animation
或者 transition
动画,这时候会碰上支持性问题。
若是你的项目须要支持如下系统版本,那么建议直接使用真实元素:
iOS Safari6.1及如下
Android Browser4.1.*及如下
,包括一些深度定制的系统,好比:
在 Android Browser4.2.*及如下
(可能版本稍有出入)(包括坑爹的Flyme),若是你有这样一段代码:
input:checked ~ .test {
background-color: #f00;
}
复制代码
那么将无任何效果,若是你想使得上述代码生效,有2种方式:
第一种,使用 input
和 +
进行激活:
html + input {}
input:checked ~ .test {
background-color: #f00;
}
复制代码
只要存在 input
和 +
选择符配合使用的选择器(空规则集也行)便可使得上述代码激活生效。
第二种,直接换成 +
:
input:checked + .test {
background-color: #f00;
}
复制代码
flex items(flex子项)
;
Android Browser4.3及如下
,iOS Safari6.1及如下
的flex子项
须要使用块级元素,在这些版本之上还可使用行内块元素
在这些版本中,若是你发现flex子项之间出现了间隙,或者在未定义换行的状况下子项自身抑或子项之间换行了,或者出现了其它不正常的状况,那么仔细看一下flex子项多是使用了行内级元素;
flex子项
子项定义 width
为非 auto
的值
Android Browser4.3及如下
,iOS Safari6.1及如下
的flex子项
若是没有显式的定义width
为非auto
的值,那么子项分配父元素剩余空间时将会不符合标准预期;
flex子项
子项定义 height
为非 auto
的值
Android Browser4.3及如下
,iOS Safari6.1及如下
的flex子项
若是没有显式的定义height
为非auto
的值,那么子项分配父元素剩余空间时将会不符合标准预期;
若是你是从pc
开发转到移动平台的,或者应该记得在pc
端,Chrome
及后来加入Webkit阵营的Opera
都不支持页面字号小于12px
,固然你能够经过更改浏览器设置来改变这一状况,而后这并无什么卵用,不是么?
不幸的是,在移动端这个限制也依然存在,在Android Chrome
上(包括部分版本上的Android Browser
),仍然不支持小于12px的字号(测试至Android5.0.2, Chrome46),除此以外,其余浏览器包括iOS上众浏览器都可以很好的支持超小字体。
因此,若是但愿你的程序足够安全,尽可能不要定义小于12px的字号,或者换一种方式来实现。
题外话:假设你的项目使用了
rem
,那么不要使用10
做为换算因子,缘由也如上
我知道不少人已经开始使用 rem
做为项目中的单位了。可是遗憾的是,在 Chrome
和 Opera
上,若是咱们给 body
元素应用了 rem
,那么这个取值将会计算错误。
假设咱们有以下代码:
html {
font-size: 62.5%;
}
body {
font-size: 1.4rem;
}
复制代码
由于大部分浏览器的默认字号都是 16px
,因此 html
的字号计算出来应该是 16px * 62.5% = 10px
。此时,咱们预期 body
的 font-size
为 14px
。然而实际状况与咱们想象的不太同样,最终 body
的计算值并非 14px
,它忽略了 html
的定义,而是直接使用了浏览器的默认字号做为参照。因而最终计算值为:16px * 1.4rem = 22.4px
。测至 chrome 45.0
和 Opera 33.0
仍然存在这个问题,不过 chrome 49.0
和 Opera 37.0
看起来已经被修复了。
为了有效的绕过这个问题,而且实现相同的效果,咱们能够将代码修改以下:
html {
font-size: 62.5%;
}
body {
font-size: 1.4em;
}
复制代码
因为 body
是 html
的直接子元素,因此此时对 body
使用 em
与 rem
的效果是相同的。
很严肃的和你们说,若是你在使用 rem
这项技术,那么尽量不要对html设置百分比大小的字号。好比这样的:
html {
font-size: 62.5%;
}
复制代码
因为大部分浏览器的默认字号是 16px
,因此能计算出 html
的字号实际为 10px
。咱们在 为何小于12px字号不生效 中说过,部分浏览器会将小于 12px
的字变成 12px
来显示。那么此时,在这些浏览器下,若是我作了这样的定义:
.demo {
width: 10rem;
}
复制代码
你预期获得 10px * 10rem = 100px
,但实际上获得的确是 12px * 10rem = 120px
。这是很是大的错误,咱们应当尽可能避免。
与此同时,虽然大部分浏览器的默认字号是 16px
,但仍然有使用其它默认值的浏览器,好比我依稀记得 firefox
使用了 15px
。并且最重要的是,用户是能够改变浏览器默认字号的,因此你认为的可能并非你认为的。
因此不要对html设置百分比字号,尤为是不要对它使用计算值比 12px
小的字号。我推荐你们这样作:
html {
font-size: 100px;
}
复制代码
以 100px
做为因子,计算也很是方便。若是你想要设置一个元素的宽度是 20px
,那么只须要:
.demo {
width: .2rem;
}
复制代码
一般当你在手机或者pad上长按图像 img
,会弹出选项 存储图像
或者 拷贝图像
,若是你不想让用户这么操做,那么你能够经过如下方法来禁止:
img {
-webkit-touch-callout: none;
}
复制代码
须要注意的是,该方法只在
iOS
上有效。
在移动设备上,全部设置了伪类 :active
的元素,默认都会在激活状态时,显示高亮框,若是不想要这个高亮,那么你能够经过如下方法来禁止:
.xxx {
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
复制代码
若是你不想用户能够选中页面中的内容,那么你能够禁掉:
html {
-webkit-user-select: none;
}
复制代码
在iOS上若是你想让一个元素拥有像 Native 的滚动效果,你能够这样作:
.xxx {
overflow: auto; /* auto | scroll */
-webkit-overflow-scrolling: touch; /* 该规则可能引发iOS UIWebView崩溃 */
}
复制代码
iOS Safari
容许用户将一个网页添加到主屏幕而后像 App
同样来操做它。咱们知道每一个 App
下方都会有一个名字,iOS Safari
提供了一个私有的 meta
来定义这个名字,代码以下:
<meta name="apple-mobile-web-app-title" content="Web App名称" />
复制代码
Android Chrome31.0
,Android Browser5.0
也开始支持添加到主屏幕了,但并无提供相应的定义标题的方式,因此若是你想统一 iOS
和 Android
平台定义 Web app 名称的方式,可使用 title
标签来定义,代码以下:
<title>Web App名称</title>
复制代码
但若是你想要网页标题和App名字不同的话,那就只有iOS才行。
当咱们将一个网页添加到主屏幕时,除了会须要设置标题以外,确定还须要可以自定义这个App的图标,代码以下:
<link rel="apple-touch-icon" href="app.png" />
复制代码
不过该方案,在拟物设计的 iOS6及之前
会自动为图标添加一层高光效果,iOS7
已使用了扁平化设计,因此若是使用该方案,在不一样版本下获得的效果会不一致。
固然,你也可使用原图做为App的图标,用以保持各平台表现一致,代码以下:
<link rel="apple-touch-icon-precomposed" href="app.png" />
复制代码
若是你想给不一样的设备定不一样的图标,能够经过 sizes
属性来定义,形如:
<link rel="apple-touch-icon" sizes="76x76" href="ipad.png@1x" />
<link rel="apple-touch-icon" sizes="120x120" href="iphone-retina@2x.png" />
<link rel="apple-touch-icon" sizes="152x152" href="ipad-retina@2x.png" />
<link rel="apple-touch-icon" sizes="180x180" href="iphone-retina@3x.png" />
复制代码
规则以下:
实际状况下,大部分智能手机都接近或者已经达到视网膜屏质量,因此若是想省事的话,能够分别为 iPhone
和 iPad
定义一种高质量的 icon
便可。
该方案在 iOS
和 Android5.0+
上都通用。
当咱们将一个网页添加到主屏幕时,会更但愿它能有像 App
同样的表现,没有地址栏和状态栏全屏显示,代码以下:
<meta name="apple-mobile-web-app-capable" content="yes" />
复制代码
该方案在 iOS
和 Android5.0+
上都通用。
当咱们将一个网页添加到主屏幕时,还能够对 系统显示手机信号、时间、电池的顶部状态栏
颜色进行设置,前提是开启了:
<meta name="apple-mobile-web-app-capable" content="yes" />
复制代码
有了这个前提,你能够经过下面的方式来进行定义:
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
复制代码
content只有3个固定值可选:default | black | black-translucent
default
,状态栏将为正常的,即白色,网页从状态栏如下开始显示;black
,状态栏将为黑色,网页从状态栏如下开始显示;black-translucent
,状态栏将为灰色半透明,网页将充满整个屏幕,状态栏会盖在网页之上;该设置只在 iOS
上有效。
在 iOS Safari
(其余浏览器和Android均不会)上会对那些看起来像是电话号码的数字处理为电话连接,好比:
可能还有其余类型的数字也会被识别,但在具体的业务场景中,有些时候这是没必要须的,因此你能够关闭电话自动识别,而后在须要拨号的地方,开启电话呼出和短信功能。
<meta name="format-detection" content="telephone=no" />
复制代码
<a href="tel:123456">123456</a>
复制代码
<a href="sms:123456">123456</a>
复制代码
在 Android
(iOS不会)上,浏览器会自动识别看起来像邮箱地址的字符串,不论有你没有加上邮箱连接,当你在这个字符串上长按,会弹出发邮件的提示。
<meta name="format-detection" content="email=no" />
复制代码
<a href="mailto:dooyoe@gmail.com">dooyoe@gmail.com</a>
复制代码
若是想同时关闭电话和邮箱识别,能够把它们写到一条 meta 内,代码以下:
<meta name="format-detection" content="telephone=no,email=no" />
复制代码
在iOS中,默认状况下键盘是开启首字母大写的功能的,若是业务不想出现首字母大写,能够这样:
<input type="text" autocapitalize="off" />
复制代码
在iOS中,默认输入法会开启自动修正输入内容的功能,若是不须要的话,能够这样:
<input type="text" autocorrect="off" />
复制代码
当移动设备横竖屏切换时,文本的大小会从新计算,进行相应的缩放,当咱们不须要这种状况时,能够选择禁止:
html {
-webkit-text-size-adjust: 100%;
}
复制代码
须要注意的是,PC端的该属性已经被移除,该属性在移动端要生效,必须设置 `meta viewport'
待续啊待续。。。