本文檔針對移動前端開發,包括 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'
待續啊待續。。。