移動端經驗速遞

概要

本文檔針對移動前端開發,包括 Hybrid 裏面的web頁面,非 Native 應用,適用於iOS6.0+, Android4.0+,是多年積累的經驗,分享給你們。css

目錄

兼容性

CSS僞類:active

若是你想使用元素的僞類來實現 按下激活 狀態,那麼你須要知道如下問題:html

  • iOS上的幾乎任何瀏覽器,定義元素的僞類 :active 都是無效;
  • Android上,Android BrowserChrome 都支持僞類 :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輸入框禁用文本色

iOS 上,若是將輸入框 disabled,此時輸入框內的文字顏色將比 color 所定義的要淺,而且沒法經過給輸入框的僞類 :disabled 定義 color 來修正。chrome

想解決這個問題,能夠做以下設置,定義輸入框的文本填充色:api

input:disabled {
	-webkit-text-fill-color: #000;
}
複製代碼

須要注意的是,在 Mac 上的 Safari 也有一樣的問題。瀏覽器

Samsung S4圓角Bug

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.*及如下,包括一些深度定製的系統,好比:
    • 魅族 - Flyme OS 4.1.1.1C及如下(比這高的版本還沒有測試過)- 咱國產能別這麼坑麼(安卓版本爲4.4.4的魅族MX4 pro)

:checked與兄弟選擇符一塊兒使用的bug

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佈局不生效

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 的值,那麼子項分配父元素剩餘空間時將會不符合標準預期;

爲何小於12px字號不生效

若是你是從pc開發轉到移動平臺的,或者應該記得在pc端,Chrome及後來加入Webkit陣營的Opera都不支持頁面字號小於12px,固然你能夠經過更改瀏覽器設置來改變這一狀況,而後這並無什麼卵用,不是麼?

不幸的是,在移動端這個限制也依然存在,在Android Chrome上(包括部分版本上的Android Browser),仍然不支持小於12px的字號(測試至Android5.0.2, Chrome46),除此以外,其餘瀏覽器包括iOS上衆瀏覽器都可以很好的支持超小字體。

因此,若是但願你的程序足夠安全,儘可能不要定義小於12px的字號,或者換一種方式來實現。

題外話:假設你的項目使用了rem,那麼不要使用10做爲換算因子,緣由也如上

chrome中body使用rem失效

我知道不少人已經開始使用 rem 做爲項目中的單位了。可是遺憾的是,在 ChromeOpera 上,若是咱們給 body 元素應用了 rem,那麼這個取值將會計算錯誤。

假設咱們有以下代碼:

html {
  font-size: 62.5%;
}
body {
  font-size: 1.4rem;
}
複製代碼

由於大部分瀏覽器的默認字號都是 16px,因此 html 的字號計算出來應該是 16px * 62.5% = 10px。此時,咱們預期 bodyfont-size14px。然而實際狀況與咱們想象的不太同樣,最終 body 的計算值並非 14px,它忽略了 html 的定義,而是直接使用了瀏覽器的默認字號做爲參照。因而最終計算值爲:16px * 1.4rem = 22.4px。測至 chrome 45.0Opera 33.0 仍然存在這個問題,不過 chrome 49.0Opera 37.0 看起來已經被修復了。

爲了有效的繞過這個問題,而且實現相同的效果,咱們能夠將代碼修改以下:

html {
  font-size: 62.5%;
}
body {
  font-size: 1.4em;
}
複製代碼

因爲 bodyhtml 的直接子元素,因此此時對 body 使用 emrem 的效果是相同的。

不要對html設置百分比字號

很嚴肅的和你們說,若是你在使用 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 上有效。

取消touch高亮

在移動設備上,全部設置了僞類 :active 的元素,默認都會在激活狀態時,顯示高亮框,若是不想要這個高亮,那麼你能夠經過如下方法來禁止:

.xxx {
	-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
複製代碼

禁止選中內容

若是你不想用戶能夠選中頁面中的內容,那麼你能夠禁掉:

html {
	-webkit-user-select: none;
}
複製代碼

快速回彈滾動

  1. 早期的時候,移動端的瀏覽器都不支持非body元素的滾動條,因此通常都藉助 iScroll;
  2. Android 3.0/iOS解決了非body元素的滾動問題,但滾動條不可見,同時iOS上只能經過2個手指進行滾動;
  3. Android 4.0解決了滾動條不可見及增長了快速回彈滾動效果,不過隨後這個特性又被移除;
  4. iOS從5.0開始解決了滾動條不可見及增長了快速回彈滾動效果

在iOS上若是你想讓一個元素擁有像 Native 的滾動效果,你能夠這樣作:

.xxx {
	overflow: auto; /* auto | scroll */
	-webkit-overflow-scrolling: touch; /* 該規則可能引發iOS UIWebView崩潰 */
}
複製代碼

設置添加到主屏幕的Web App標題

iOS Safari 容許用戶將一個網頁添加到主屏幕而後像 App 同樣來操做它。咱們知道每一個 App 下方都會有一個名字,iOS Safari 提供了一個私有的 meta 來定義這個名字,代碼以下:

<meta name="apple-mobile-web-app-title" content="Web App名稱" />
複製代碼

Android Chrome31.0Android Browser5.0 也開始支持添加到主屏幕了,但並無提供相應的定義標題的方式,因此若是你想統一 iOSAndroid 平臺定義 Web app 名稱的方式,可使用 title 標籤來定義,代碼以下:

<title>Web App名稱</title>
複製代碼

但若是你想要網頁標題和App名字不同的話,那就只有iOS才行。

設置添加到主屏幕的Web App圖標

當咱們將一個網頁添加到主屏幕時,除了會須要設置標題以外,確定還須要可以自定義這個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" />
複製代碼

規則以下:

  • 若是沒有跟相應設備推薦尺寸一致的圖標,會優先選擇比推薦尺寸大而且最接近推薦尺寸的圖標。
  • 若是沒有比推薦尺寸大的圖標,會優先選擇最接近推薦尺寸的圖標。
  • 若是有多個圖標符合推薦尺寸,會優先選擇包含關鍵字precomposed的圖標。

實際狀況下,大部分智能手機都接近或者已經達到視網膜屏質量,因此若是想省事的話,能夠分別爲 iPhoneiPad 定義一種高質量的 icon 便可。

該方案在 iOSAndroid5.0+ 上都通用。

添加到主屏幕時隱藏地址欄和狀態欄(即全屏)

當咱們將一個網頁添加到主屏幕時,會更但願它能有像 App 同樣的表現,沒有地址欄和狀態欄全屏顯示,代碼以下:

<meta name="apple-mobile-web-app-capable" content="yes" />
複製代碼

該方案在 iOSAndroid5.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均不會)上會對那些看起來像是電話號碼的數字處理爲電話連接,好比:

  • 7位數字,形如:1234567
  • 帶括號及加號的數字,形如:(+86)123456789
  • 雙鏈接線的數字,形如:00-00-00111
  • 11位數字,形如:13800138000

可能還有其餘類型的數字也會被識別,但在具體的業務場景中,有些時候這是沒必要須的,因此你能夠關閉電話自動識別,而後在須要撥號的地方,開啓電話呼出和短信功能。

  1. 關閉電話號碼識別:
<meta name="format-detection" content="telephone=no" />
複製代碼
  1. 開啓撥打電話功能:
<a href="tel:123456">123456</a>
複製代碼
  1. 開啓發送短信功能:
<a href="sms:123456">123456</a>
複製代碼

郵箱地址識別

Android (iOS不會)上,瀏覽器會自動識別看起來像郵箱地址的字符串,不論有你沒有加上郵箱連接,當你在這個字符串上長按,會彈出發郵件的提示。

  1. 關閉郵箱地址識別:
<meta name="format-detection" content="email=no" />
複製代碼
  1. 開啓郵件發送:
<a href="mailto:dooyoe@gmail.com">dooyoe@gmail.com</a>
複製代碼

若是想同時關閉電話和郵箱識別,能夠把它們寫到一條 meta 內,代碼以下:

<meta name="format-detection" content="telephone=no,email=no" />
複製代碼

關閉iOS鍵盤首字母自動大寫

在iOS中,默認狀況下鍵盤是開啓首字母大寫的功能的,若是業務不想出現首字母大寫,能夠這樣:

<input type="text" autocapitalize="off" />
複製代碼

關閉iOS輸入自動修正

在iOS中,默認輸入法會開啓自動修正輸入內容的功能,若是不須要的話,能夠這樣:

<input type="text" autocorrect="off" />
複製代碼

禁止文本縮放

當移動設備橫豎屏切換時,文本的大小會從新計算,進行相應的縮放,當咱們不須要這種狀況時,能夠選擇禁止:

html {
	-webkit-text-size-adjust: 100%;
}
複製代碼

須要注意的是,PC端的該屬性已經被移除,該屬性在移動端要生效,必須設置 `meta viewport'

性能優化

待續啊待續。。。

相關文章
相關標籤/搜索