trip
移動(dòng)端經(jīng)驗(yàn)速遞
引用自杜瑤github
概要
本文檔針對(duì)移動(dòng)前端開發(fā),包括 Hybrid
里面的web頁面乌助,非 Native
應(yīng)用噪奄。
適用
所有經(jīng)驗(yàn)適用于:iOS6.0+
, Android4.0+
目錄
<a name="compatibility"></a>
兼容性
<a name="active"></a>
CSS偽類:active
如果你想使用元素的偽類來實(shí)現(xiàn) 按下激活
狀態(tài),那么你需要知道以下問題:
- iOS上的幾乎任何瀏覽器囚衔,定義元素的偽類
:active
都是無效眷射; - Android上匙赞,
Android Browser
和Chrome
都支持偽類:active
佛掖,其它第三方瀏覽器有部分不支持妖碉; - 定義了
:active
并且當(dāng)前瀏覽器環(huán)境支持,當(dāng)手指在滾動(dòng)或者無意間的劃過時(shí)芥被,:active
狀態(tài)都會(huì)被激活欧宜;
為了規(guī)避上述所有的問題,如果需要
按下激活
狀態(tài)拴魄,推薦使用js
新增一個(gè)className
<a name="input-shadow"></a>
清除輸入框內(nèi)陰影
iOS上的幾乎任何瀏覽器輸入框(input, textarea)默認(rèn)有內(nèi)部陰影冗茸,但無法使用 box-shadow
來清除,如果不需要陰影匹中,可以這樣關(guān)閉:
input,
textarea {
/* 方法1: 去掉邊框 */
border: 0;
/* 方法2: 邊框色透明 */
border-color: transparent;
/* 方法3: 重置輸入框默認(rèn)外觀 */
-webkit-appearance: none;
appearance: none;
}
<a name="s4-radius"></a>
Samsung S4圓角Bug
Samsung S4
手機(jī)在 Android Browser4.4.2
上(其他版本未測(cè))夏漱,如果你使用了 border-radius
,并且使用了 -webkit-transform
屬性顶捷,當(dāng)使用了 translatez
或者 translate3d
值挂绰,圓角會(huì)出現(xiàn)問題:
.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)
將會(huì)導(dǎo)致圓角無法包裹住 background-color
服赎。
當(dāng)然葵蒂,-webkit-transform: translate3d(0, 0, 0)
也是一樣的,所以如果你的某個(gè)場(chǎng)景是這樣的重虑,那么可以直接使用 -webkit-transform: translate(0, 0)
來避免這個(gè)問題践付。
<a name="background-overflow"></a>
邊框圓角致背景溢出
在紅米和OPPO等手機(jī)某些版本的 Android Webview
中,如果一個(gè)元素定義了 border
+ border-radius
缺厉,這時(shí)如果該元素有背景永高,那么背景將會(huì)溢出圓角之外隧土。
之所以會(huì)出現(xiàn)這個(gè)問題:其主要原因是因?yàn)镃SS對(duì)背景裁剪(background-clip)有不同的處理方式,通常它可以是 border-box | padding-box | content-box
這3種方式乏梁。
瀏覽器的默認(rèn)裁減方式是 border-box
次洼,即溢出 border
之外的背景都將被裁減。
對(duì)于上述無法裁減邊框之外背景的手機(jī)遇骑,將值定義為 padding-box | content-box
都能fix這問題卖毁,不過更推薦使用 padding-box
。因?yàn)槭褂?content-box
落萎,如果定義了 padding
不為 0
亥啦,背景將無法鋪滿元素。
<a name="border-radius-percentage"></a>
一個(gè)失敗的圓(圓角)
在移動(dòng)平臺(tái)上開發(fā)時(shí)练链,用CSS畫一個(gè)圓很簡(jiǎn)單翔脱,只需要一句代碼:
.circle {
border-radius: 50%;
}
不過,在 Android Browser2.*
上媒鼓,這個(gè)定義將會(huì)失效届吁,而顯示為默認(rèn)的矩形。
因?yàn)?Android Browser2.*
不支持以 百分比
作為 border-radius
的值绿鸣,所以如果你需要兼容 Android Browser2.*
疚沐,那么你可以這樣:
.circle {
width: 10rem;
height: 10rem;
border-radius: 5rem;
}
如果你覺得這樣定義不夠靈活,想懶一點(diǎn)潮模,那么其實(shí)可以給 border-radius
預(yù)設(shè)一個(gè)比較大的值亮蛔,比如 100rem
,用以避免當(dāng)元素的尺寸變了擎厢,圓角半徑也得跟著變究流,除非元素的尺寸超出了你預(yù)設(shè)的閥值。
<a name="pseudo-element-animation"></a>
不要使用偽元素動(dòng)畫
有的時(shí)候你可能會(huì)為了減少頁面上的DOM數(shù)动遭,而使用偽元素芬探。但如果你想給偽元素增加 animation
或者 transition
動(dòng)畫,這時(shí)候會(huì)碰上支持性問題厘惦。
如果你的項(xiàng)目需要支持以下系統(tǒng)版本偷仿,那么建議直接使用真實(shí)元素:
iOS Safari6.1及以下
-
Android Browser4.1.*及以下
,包括一些深度定制的系統(tǒng)绵估,比如:- 魅族 - Flyme OS 4.1.1.1C及以下(比這高的版本尚未測(cè)試過)- 咱國(guó)產(chǎn)能別這么坑么(安卓版本為4.4.4的魅族MX4 pro)
<a name="checked-sibling-bug"></a>
:checked與兄弟選擇符一起使用的bug
在 Android Browser4.2.*及以下
(可能版本稍有出入)(包括坑爹的Flyme)炎疆,如果你有這樣一段代碼:
input:checked ~ .test {
background-color: #f00;
}
那么將無任何效果,如果你想使得上述代碼生效国裳,有2種方式:
第一種形入,使用 input
和 +
進(jìn)行激活:
html + input {}
input:checked ~ .test {
background-color: #f00;
}
只要存在 input
和 +
選擇符配合使用的選擇器(空規(guī)則集也行)即可使得上述代碼激活生效。
第二種缝左,直接換成 +
:
input:checked + .test {
background-color: #f00;
}
<a name="flex"></a>
為什么flex布局不生效
- 使用塊級(jí)元素作為
flex items(flex子項(xiàng))
亿遂;
Android Browser4.3及以下
浓若,iOS Safari6.1及以下
的flex子項(xiàng)
需要使用塊級(jí)元素,在這些版本之上還可以使用行內(nèi)塊元素
在這些版本中蛇数,如果你發(fā)現(xiàn)flex子項(xiàng)之間出現(xiàn)了間隙挪钓,或者在未定義換行的情況下子項(xiàng)自身抑或子項(xiàng)之間換行了,或者出現(xiàn)了其它不正常的情況耳舅,那么仔細(xì)看一下flex子項(xiàng)可能是使用了行內(nèi)級(jí)元素碌上;
- 當(dāng)橫向布局時(shí),給
flex子項(xiàng)
子項(xiàng)定義width
為非auto
的值
Android Browser4.3及以下
浦徊,iOS Safari6.1及以下
的flex子項(xiàng)
如果沒有顯式的定義width
為非auto
的值馏予,那么子項(xiàng)分配父元素剩余空間時(shí)將會(huì)不符合標(biāo)準(zhǔn)預(yù)期;
- 當(dāng)縱向布局時(shí)盔性,給
flex子項(xiàng)
子項(xiàng)定義height
為非auto
的值
Android Browser4.3及以下
霞丧,iOS Safari6.1及以下
的flex子項(xiàng)
如果沒有顯式的定義height
為非auto
的值,那么子項(xiàng)分配父元素剩余空間時(shí)將會(huì)不符合標(biāo)準(zhǔn)預(yù)期冕香;
<a name="12px"></a>
為什么小于12px字號(hào)不生效
如果你是從pc
開發(fā)轉(zhuǎn)到移動(dòng)平臺(tái)的蛹尝,或者應(yīng)該記得在pc
端,Chrome
及后來加入Webkit陣營(yíng)的Opera
都不支持頁面字號(hào)小于12px
悉尾,當(dāng)然你可以通過更改瀏覽器設(shè)置來改變這一情況突那,然后這并沒有什么卵用,不是么焕襟?
不幸的是陨收,在移動(dòng)端這個(gè)限制也依然存在饭豹,在Android Chrome
上(包括部分版本上的Android Browser
)鸵赖,仍然不支持小于12px的字號(hào)(測(cè)試至Android5.0.2, Chrome46),除此之外拄衰,其他瀏覽器包括iOS上眾瀏覽器都能夠很好的支持超小字體它褪。
所以,如果希望你的程序足夠安全茫打,盡量不要定義小于12px的字號(hào),或者換一種方式來實(shí)現(xiàn)妖混。
題外話:假設(shè)你的項(xiàng)目使用了
rem
老赤,那么不要使用10
作為換算因子,原因也如上
<a name="chrome-rem-bug"></a>
chrome中body使用rem失效
我知道很多人已經(jīng)開始使用 rem
作為項(xiàng)目中的單位了制市。但是遺憾的是抬旺,在 Chrome
和 Opera
上,如果我們給 body
元素應(yīng)用了 rem
祥楣,那么這個(gè)取值將會(huì)計(jì)算錯(cuò)誤开财。
假設(shè)我們有如下代碼:
html {
font-size: 62.5%;
}
body {
font-size: 1.4rem;
}
因?yàn)榇蟛糠譃g覽器的默認(rèn)字號(hào)都是 16px
汉柒,所以 html
的字號(hào)計(jì)算出來應(yīng)該是 16px * 62.5% = 10px
。此時(shí)责鳍,我們預(yù)期 body
的 font-size
為 14px
碾褂。然而實(shí)際情況與我們想象的不太一樣,最終 body
的計(jì)算值并不是 14px
历葛,它忽略了 html
的定義正塌,而是直接使用了瀏覽器的默認(rèn)字號(hào)作為參照。于是最終計(jì)算值為:16px * 1.4rem = 22.4px
恤溶。測(cè)至 chrome 45.0
和 Opera 33.0
仍然存在這個(gè)問題传货,不過 chrome 49.0
和 Opera 37.0
看起來已經(jīng)被修復(fù)了。
為了有效的繞過這個(gè)問題宏娄,并且實(shí)現(xiàn)相同的效果问裕,我們可以將代碼修改如下:
html {
font-size: 62.5%;
}
body {
font-size: 1.4em;
}
由于 body
是 html
的直接子元素孵坚,所以此時(shí)對(duì) body
使用 em
與 rem
的效果是相同的粮宛。
<a name="html-percent-font-size"></a>
不要對(duì)html設(shè)置百分比字號(hào)
很嚴(yán)肅的和大家說,如果你在使用 rem
這項(xiàng)技術(shù)卖宠,那么盡可能不要對(duì)html設(shè)置百分比大小的字號(hào)巍杈。比如這樣的:
html {
font-size: 62.5%;
}
由于大部分瀏覽器的默認(rèn)字號(hào)是 16px
,所以能計(jì)算出 html
的字號(hào)實(shí)際為 10px
扛伍。我們?cè)?為什么小于12px字號(hào)不生效 中說過筷畦,部分瀏覽器會(huì)將小于 12px
的字變成 12px
來顯示。那么此時(shí)刺洒,在這些瀏覽器下鳖宾,如果我做了這樣的定義:
.demo {
width: 10rem;
}
你預(yù)期得到 10px * 10rem = 100px
,但實(shí)際上得到的確是 12px * 10rem = 120px
逆航。這是非常大的錯(cuò)誤鼎文,我們應(yīng)當(dāng)盡量避免。
與此同時(shí)因俐,雖然大部分瀏覽器的默認(rèn)字號(hào)是 16px
拇惋,但仍然有使用其它默認(rèn)值的瀏覽器,比如我依稀記得 firefox
使用了 15px
抹剩。而且最重要的是撑帖,用戶是可以改變?yōu)g覽器默認(rèn)字號(hào)的,所以你認(rèn)為的可能并不是你認(rèn)為的澳眷。
所以不要對(duì)html設(shè)置百分比字號(hào)胡嘿,尤其是不要對(duì)它使用計(jì)算值比 12px
小的字號(hào)。我推薦大家這樣做:
html {
font-size: 100px;
}
以 100px
作為因子境蔼,計(jì)算也非常方便灶平。如果你想要設(shè)置一個(gè)元素的寬度是 20px
伺通,那么只需要:
.demo {
width: .2rem;
}
<a name="experience"></a>
經(jīng)驗(yàn)
<a name="touch-callout"></a>
禁止保存或拷貝圖像
通常當(dāng)你在手機(jī)或者pad上長(zhǎng)按圖像 img
,會(huì)彈出選項(xiàng) 存儲(chǔ)圖像
或者 拷貝圖像
逢享,如果你不想讓用戶這么操作罐监,那么你可以通過以下方法來禁止:
img {
-webkit-touch-callout: none;
}
需要注意的是,該方法只在
iOS
上有效瞒爬。
<a name="tap-highlight-color"></a>
取消touch高亮
在移動(dòng)設(shè)備上弓柱,所有設(shè)置了偽類 :active
的元素,默認(rèn)都會(huì)在激活狀態(tài)時(shí)侧但,顯示高亮框矢空,如果不想要這個(gè)高亮,那么你可以通過以下方法來禁止:
.xxx {
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
<a name="user-select"></a>
禁止選中內(nèi)容
如果你不想用戶可以選中頁面中的內(nèi)容禀横,那么你可以禁掉:
html {
-webkit-user-select: none;
}
<a name="overflow-scrolling"></a>
快速回彈滾動(dòng)
- 早期的時(shí)候屁药,移動(dòng)端的瀏覽器都不支持非body元素的滾動(dòng)條,所以一般都借助 iScroll;
- Android 3.0/iOS解決了非body元素的滾動(dòng)問題柏锄,但滾動(dòng)條不可見酿箭,同時(shí)iOS上只能通過2個(gè)手指進(jìn)行滾動(dòng);
- Android 4.0解決了滾動(dòng)條不可見及增加了快速回彈滾動(dòng)效果趾娃,不過隨后這個(gè)特性又被移除换况;
- iOS從5.0開始解決了滾動(dòng)條不可見及增加了快速回彈滾動(dòng)效果
在iOS上如果你想讓一個(gè)元素?fù)碛邢?Native 的滾動(dòng)效果廷没,你可以這樣做:
.xxx {
overflow: auto; /* auto | scroll */
-webkit-overflow-scrolling: touch; /* 該規(guī)則可能引起iOS UIWebView崩潰 */
}
<a name="shortcut-title"></a>
設(shè)置添加到主屏幕的Web App標(biāo)題
iOS Safari
允許用戶將一個(gè)網(wǎng)頁添加到主屏幕然后像 App
一樣來操作它竟块。我們知道每個(gè) App
下方都會(huì)有一個(gè)名字少辣,iOS Safari
提供了一個(gè)私有的 meta
來定義這個(gè)名字,代碼如下:
<meta name="apple-mobile-web-app-title" content="Web App名稱" />
Android Chrome31.0
笤成,Android Browser5.0
也開始支持添加到主屏幕了评架,但并沒有提供相應(yīng)的定義標(biāo)題的方式,所以如果你想統(tǒng)一 iOS
和 Android
平臺(tái)定義 Web app 名稱的方式疹启,可以使用 title
標(biāo)簽來定義古程,代碼如下:
<title>Web App名稱</title>
但如果你想要網(wǎng)頁標(biāo)題和App名字不一樣的話蔼卡,那就只有iOS才行喊崖。
<a name="shortcut-icon"></a>
設(shè)置添加到主屏幕的Web App圖標(biāo)
當(dāng)我們將一個(gè)網(wǎng)頁添加到主屏幕時(shí),除了會(huì)需要設(shè)置標(biāo)題之外雇逞,肯定還需要能夠自定義這個(gè)App的圖標(biāo)荤懂,代碼如下:
<link rel="apple-touch-icon" href="app.png" />
不過該方案,在擬物設(shè)計(jì)的 iOS6及以前
會(huì)自動(dòng)為圖標(biāo)添加一層高光效果塘砸,iOS7
已使用了扁平化設(shè)計(jì)节仿,所以如果使用該方案,在不同版本下得到的效果會(huì)不一致掉蔬。
當(dāng)然廊宪,你也可以使用原圖作為App的圖標(biāo)矾瘾,用以保持各平臺(tái)表現(xiàn)一致,代碼如下:
<link rel="apple-touch-icon-precomposed" href="app.png" />
如果你想給不同的設(shè)備定不同的圖標(biāo)箭启,可以通過 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" />
規(guī)則如下:
- 如果沒有跟相應(yīng)設(shè)備推薦尺寸一致的圖標(biāo),會(huì)優(yōu)先選擇比推薦尺寸大并且最接近推薦尺寸的圖標(biāo)傅寡。
- 如果沒有比推薦尺寸大的圖標(biāo)放妈,會(huì)優(yōu)先選擇最接近推薦尺寸的圖標(biāo)。
- 如果有多個(gè)圖標(biāo)符合推薦尺寸荐操,會(huì)優(yōu)先選擇包含關(guān)鍵字precomposed的圖標(biāo)芜抒。
實(shí)際情況下,大部分智能手機(jī)都接近或者已經(jīng)達(dá)到視網(wǎng)膜屏質(zhì)量托启,所以如果想省事的話宅倒,可以分別為 iPhone
和 iPad
定義一種高質(zhì)量的 icon
即可。
該方案在 iOS
和 Android5.0+
上都通用屯耸。
<a name="hide-bar"></a>
添加到主屏幕時(shí)隱藏地址欄和狀態(tài)欄(即全屏)
當(dāng)我們將一個(gè)網(wǎng)頁添加到主屏幕時(shí)唉堪,會(huì)更希望它能有像 App
一樣的表現(xiàn),沒有地址欄和狀態(tài)欄全屏顯示肩民,代碼如下:
<meta name="apple-mobile-web-app-capable" content="yes" />
該方案在 iOS
和 Android5.0+
上都通用唠亚。
<a name="status-bar-style"></a>
添加到主屏幕時(shí)設(shè)置系統(tǒng)頂欄顏色
當(dāng)我們將一個(gè)網(wǎng)頁添加到主屏幕時(shí),還可以對(duì) 系統(tǒng)顯示手機(jī)信號(hào)持痰、時(shí)間灶搜、電池的頂部狀態(tài)欄
顏色進(jìn)行設(shè)置,前提是開啟了:
<meta name="apple-mobile-web-app-capable" content="yes" />
有了這個(gè)前提工窍,你可以通過下面的方式來進(jìn)行定義:
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
content只有3個(gè)固定值可選:default | black | black-translucent
- 如果設(shè)置為
default
割卖,狀態(tài)欄將為正常的,即白色患雏,網(wǎng)頁從狀態(tài)欄以下開始顯示鹏溯; - 如果設(shè)置為
black
,狀態(tài)欄將為黑色淹仑,網(wǎng)頁從狀態(tài)欄以下開始顯示丙挽; - 如果設(shè)置為
black-translucent
,狀態(tài)欄將為灰色半透明匀借,網(wǎng)頁將充滿整個(gè)屏幕颜阐,狀態(tài)欄會(huì)蓋在網(wǎng)頁之上;
該設(shè)置只在 iOS
上有效吓肋。
<a name="tel"></a>
電話號(hào)碼識(shí)別
在 iOS Safari
(其他瀏覽器和Android均不會(huì))上會(huì)對(duì)那些看起來像是電話號(hào)碼的數(shù)字處理為電話鏈接凳怨,比如:
- 7位數(shù)字,形如:1234567
- 帶括號(hào)及加號(hào)的數(shù)字,形如:(+86)123456789
- 雙連接線的數(shù)字肤舞,形如:00-00-00111
- 11位數(shù)字紫新,形如:13800138000
可能還有其他類型的數(shù)字也會(huì)被識(shí)別,但在具體的業(yè)務(wù)場(chǎng)景中李剖,有些時(shí)候這是不必須的弊琴,所以你可以關(guān)閉電話自動(dòng)識(shí)別,然后在需要撥號(hào)的地方杖爽,開啟電話呼出和短信功能敲董。
- 關(guān)閉電話號(hào)碼識(shí)別:
<meta name="format-detection" content="telephone=no" />
- 開啟撥打電話功能:
<a href="tel:123456">123456</a>
- 開啟發(fā)送短信功能:
<a href="sms:123456">123456</a>
<a name="email"></a>
郵箱地址識(shí)別
在 Android
(iOS不會(huì))上,瀏覽器會(huì)自動(dòng)識(shí)別看起來像郵箱地址的字符串慰安,不論有你沒有加上郵箱鏈接腋寨,當(dāng)你在這個(gè)字符串上長(zhǎng)按,會(huì)彈出發(fā)郵件的提示化焕。
- 關(guān)閉郵箱地址識(shí)別:
<meta name="format-detection" content="email=no" />
- 開啟郵件發(fā)送:
<a href="mailto:dooyoe@gmail.com">dooyoe@gmail.com</a>
如果想同時(shí)關(guān)閉電話和郵箱識(shí)別萄窜,可以把它們寫到一條 meta 內(nèi),代碼如下:
<meta name="format-detection" content="telephone=no,email=no" />
<a name="autocapitalize"></a>
關(guān)閉iOS鍵盤首字母自動(dòng)大寫
在iOS中撒桨,默認(rèn)情況下鍵盤是開啟首字母大寫的功能的查刻,如果業(yè)務(wù)不想出現(xiàn)首字母大寫,可以這樣:
<input type="text" autocapitalize="off" />
<a name="autocorrect"></a>
關(guān)閉iOS輸入自動(dòng)修正
在iOS中凤类,默認(rèn)輸入法會(huì)開啟自動(dòng)修正輸入內(nèi)容的功能穗泵,如果不需要的話,可以這樣:
<input type="text" autocorrect="off" />
<a name="text-size-adjust"></a>
禁止文本縮放
當(dāng)移動(dòng)設(shè)備橫豎屏切換時(shí)谜疤,文本的大小會(huì)重新計(jì)算佃延,進(jìn)行相應(yīng)的縮放,當(dāng)我們不需要這種情況時(shí)夷磕,可以選擇禁止:
html {
-webkit-text-size-adjust: 100%;
}
需要注意的是履肃,PC端的該屬性已經(jīng)被移除,該屬性在移動(dòng)端要生效坐桩,必須設(shè)置 `meta viewport'
<a name="performance"></a>
性能優(yōu)化
待續(xù)啊待續(xù)尺棋。。绵跷。