前面的話
本文將詳細介紹移動web開發中的常見問題
Input
【光標顏色】
默認情況下,光標顏色與字體顏色color相同,但也可以通過caret-color屬性來單獨設置
caret-color: auto; caret-color: transparent; caret-color: currentColor; caret-color: red; caret-color: #5729e9; caret-color: rgb(0, 200, 0); caret-color: hsla(228, 4%, 24%, 0.8);
但是,IOS的光標不支持caret-color,與字體顏色無關,默認為紫藍色。所以,盡量不要設置藍色或紫色背景,否則光標看不清楚
【光標高度】
input域的光標高度與行高line-height相同,所以不要設置太高的行高,可以通過設置上下padding來撐開高度
【放大】
IOS下,input獲取焦點時會放大,meta設置user-scalable=no,可取消放大效果
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no, shrink-to-fit=no">
【自動大寫】
一般地,IOS下默認開啟鍵盤的首字母自動大寫功能,這樣輸入英文的時候,首字母便會自動大寫

但是,有些時候並不希望一直是首字母大寫的。比如用戶名這個字段,如果字段本身就是區分大小寫的,首字母自動大寫往往會給用戶帶來麻煩。可以通過在表單元素上可以通過設置autocapitalize="off"
來關閉
<input type="text" autocapitalize="off">
【圓角】
IOS下,input域只顯示底邊框時,會出現兩個底部底邊圓角效果,設置border-radius:0即可
border-radius:0
【自動保存】
input域默認會開啟自動保存功能,可以使用autocomplete="off"屬性將其關閉
<input autocomplete="off" />
要特別注意的是,如果使用react框架,需要將autocomplete替換為autoComplete這種小駝峰形式
【輪廓outline】
android瀏覽器下,input域處於焦點狀態時,默認會有一圈淡黃色的輪廓outline效果
通過設置outline:none可將其去除
outline: none
【虛擬鍵盤】
IOS彈出虛擬鍵盤不影響可視區域大小,而android手機彈出虛擬鍵盤時會影響。所以,最好將包含input域的頁面高度設為固定
在頁面初始化時,獲取頁面高度
// app.js
componentDidMount() {
const { setWrapSize } = this.props const { clientHeight, clientWidth } = document.documentElement setWrapSize({ clientHeight, clientWidth }) window.addEventListener('orientationchange', this.setSize) }
然后通過行間樣式,將此高度設置到包含input域的頁面上
// BaseFullScreen <Wrap className={className} style={{ height: `${wrapHeight}px` }} {...rest}>{children}</Wrap>
樣式
【點擊背景】
在移動端,點擊可點擊元素時,android下會出現淡藍色背景,IOS下會出現灰色背景

可以通過-webkt-tap-hightlight-color屬性的設置,取消點擊時出現的背景效果
* { -webkit-tap-highlight-color: rgba(0, 0, 0, 0); }
【appearance】
使用appearance:none主要用來去除表單類元素的中瀏覽器內置樣式,如去除data類型input域的叉叉,去除number類型input域的上下箭頭等
-webkit-appearance: none;
【禁止選中】
有時不希望用戶在網站上選擇文本,或許是出於版權的原因,如電子書網站。通常使用js來實現
另一個方案就是,將-webkit-user-select設為none
-webkit-user-select:none;
【禁止文字縮放】
部分手機上,切換橫豎屏時,會縮放字體。使用如下設置,可以禁止文字縮放
* { -webkit-text-size-adjust:100%; }
【文本渲染】
使用text-rendering:optimizeLegibility屬性,可以讓瀏覽器在繪制文本時將着重考慮易讀性,而不是渲染速度和幾何精度.它會使字間距和連字有效
text-rendering: optimizeLegibility;
該屬性在移動設備上會造成比較明顯的性能問題
【文本平滑顯示】
-webkit-font-smoothing屬性可以用來控制字體的像素顯示是否平滑
none 關閉抗鋸齒,字體邊緣犀利。
antialiased 字體像素級平滑,在深色背景上會讓文字看起來更細了
subpixel-antialiased 字體亞像素級平滑,主要為了在非視網膜設備下更好的顯示
body { -webkit-font-smoothing: antialiased; }
【輪廓outline】
input、textarea等表單類標簽,在獲取焦點的情況下,在andriod系統下,會出現淡黃色輪廓outline,使用outline:none將其去除
outline: none
【placeholder】
placeholder默認是淺灰色,如果input域是淺灰色背景,則這時placeholder的文本與背景顏色相近,無法清晰顯示,就需要設置placeholder的顏色
可以通過偽元素來進行設置
::placeholder {
color: #fff;
}
【清除按鈕圓角】
input,button{ -webkit-appearance:none; border-radius:0; }
【滾動回彈】
-webkit-overflow-scrolling 屬性控制元素在移動設備上是否使用滾動回彈效果
auto 使用普通滾動, 當手指從觸摸屏上移開,滾動會立即停止
touch 使用具有回彈效果的滾動, 當手指從觸摸屏上移開,內容會繼續保持一段時間的滾動效果。繼續滾動的速度和持續的時間和滾動手勢的強烈程度成正比。同時也會創建一個新的堆棧上下文
body { -webkit-overflow-scrolling: touch; }
一定要設置該屬性,否則在IOS下會出現局部滾動不流暢的bug
【1倍行高】
設置line-height:1,即行高為1時,有的頁面會出現文字顯示不全的情況,所以行高設置一定要大於1
1像素邊框
由於retina屏的原因,1px 的 border 會顯示成兩個物理像素,所以看起來會感覺很粗,這是一個移動端開發常見的問題
解決方案有很多,但都有自己的優缺點
1、0.5px 邊框
從iOS 8開始,iOS 瀏覽器支持 0.5px 的 border,但是在 Android 上是不支持的,0.5px 會被認為是 0px,所以這種方法,兼容性很差
2、背景漸變
CSS3 有了漸變背景,可以通過漸變背景實現 1px 的 border,實現原理是設置 1px 的漸變背景,50% 有顏色,50% 是透明的
@mixin commonStyle() { background-size: 100% 1px,1px 100% ,100% 1px, 1px 100%; background-repeat: no-repeat; background-position: top, right top, bottom, left top; } @mixin border($border-color) { @include commonStyle(); background-image:linear-gradient(180deg, $border-color, $border-color 50%, transparent 50%), linear-gradient(270deg, $border-color, $border-color 50%, transparent 50%), linear-gradient(0deg, $border-color, $border-color 50%, transparent 50%), linear-gradient(90deg, $border-color, $border-color 50%, transparent 50%); }
3、偽類 + transform
這類方法的實現原理是用偽元素高度設置為1px,然后用 transform縮小到原來的一半
div { position: relative; &::after { position: absolute; left: 0; right: 0; height: 1px; transform: scaleY(.5); content: ''; } `
布局
【vh】
頁面使用vh來控制元素高度的時候,在安卓端瀏覽器虛擬鍵盤彈出時,導致視口高度改變,以至於vh的取值改變
// 正常模式下 100vh = document.documentElement.clientHeight; // 安卓端彈出虛擬鍵盤情況下 100vh = document.documentElement.clientHeight - 虛擬鍵盤的高度;
這種情況導致了在虛擬鍵盤彈出時,頁面中使用vh定高的元素的大小被壓縮,造成布局錯位以及文字溢出
所以,最好將包含input域的頁面高度設為固定
【100%與100vh】
100vh指的是視口,即屏幕高度的100%,不僅包括瀏覽器可視高度,還包括瀏覽器地址欄高度。而100%高度,是頁面高度的100%
所以,在全屏情況下,100vh等於100%高度,否則,100vh大於100%高度
【高度無效】
在IOS下,設置height:100%,如果父級的flex值為1,而沒有設置具體高度,則100%高度設置無效
處理方法是,在父級通過計算來設置具體高度height,如height: calc(100% - 100px)
事件
【鼠標事件】
由於移動設備沒有鼠標,所以與電腦端有一些不同之處
1、不支持dblclick雙擊事件。在移動設備中雙擊瀏覽器窗口會放大畫面
2、單擊元素會觸發mousemove事件
3、兩個手指放在屏幕上且頁面隨手指移動而滾動時會觸發mousewheel和scroll事件
【touch事件】
新版的chrome下,不支持直接給document和body設置touch事件,所以下列代碼無效
document.addEventListener('touchstart', function(e) { e.preventDefault(); })
圖片
【SVG】
SVG圖片由於其矢量的性質,縮放不失真,則代碼量較少,大量地應用在小圖標上。但在使用的過程中,有一些要注意的地方
1、在偽類中添加SVG,在IOS下svg不顯示
2、在頁面中添加SVG,在android的微信中下會出現設置透明度opacity的元素有的不顯示的情況,所以盡量不設置透明度
3、在mask屬性中設置SVG,可以通過background-color給SVG變換顏色
【base64】
要特別注意的是,圖片變化base64格式之后,再添加查詢字符串,會報錯
【緩存】
移動端更改同名圖片無法清除緩存。所以,還是要在圖片命名上做文章
meta
【shrink-to-fit=no】
IOS9+系統下,使用Viewport元標記"width=device-width"會導致頁面縮小以適應溢出視口邊界的內容。可以通過添加"shrink-to-fit=no"到meta標簽來覆蓋此行為,增加的值將阻止頁面縮放以適應視口
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no,shrink-to-fit=no">
【頁面縮放】
在meta標簽中設置了禁止縮放user-scalable=no,可以實現在IOS下input域焦點狀態時放大被禁止的效果。但是,仍然無法阻止頁面整體的縮放
【識別規則】
1、打電話
<a href="tel:0755-10086">打電話給:0755-10086</a>
2、發短信,winphone系統無效
<a href="sms:10086">發短信給: 10086</a>
3、跳轉到地圖
<a href="iosamap://viewMap?sourceApplication=yukapril&poiname=國宏賓館&lat=39.905592&lon=116.33604&dev=0">高德地圖</a> <a href="androidamap://viewMap?sourceApplication=yukapril&poiname=國宏賓館&lat=39.905592&lon=116.33604&dev=0">高德</a>
4、寫郵件
<a href="mailto:peun@foxmail.com">peun@foxmail.com</a>
5、禁止識別
<meta name="format-detection" content="telephone=no,email=no,address=no"/>
【爬蟲】
robots(網頁搜索引擎索引方式):對應一組使用逗號(,)分割的值,通常取值:
none:搜索引擎將忽略此網頁,等同於noindex,nofollow;
noindex:搜索引擎不索引此網頁;nofollow:搜索引擎不繼續通過此網頁的鏈接索引搜索其它的網頁;
all:搜索引擎將索引此網頁與繼續通過此網頁的鏈接索引,等同於index,follow;
index:搜索引擎索引此網頁;follow:搜索引擎繼續通過此網頁的鏈接索引搜索其它的網頁;
使用下列代碼,則網頁會被搜索引擎忽略
<meta name="robots" content="none"/>
【添加到主屏幕】
在IOS下,在head元素底部,使用下列代碼可以實現添加到主屏幕的功能
<meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="black"> <meta name="apple-mobile-web-app-title" content="Weather PWA"> <link rel="apple-touch-icon" href="images/icons/icon-152x152.png">
【QQ瀏覽器】
// 全屏模式 <meta name="x5-fullscreen" content="true"> // 強制豎屏 <meta name="x5-orientation" content="portrait"> // 強制橫屏 <meta name="x5-orientation" content="landscape"> // 應用模式 <meta name="x5-page-mode" content="app">
【UC瀏覽器】
// 全屏模式 <meta name="full-screen" content="yes"> // 強制豎屏 <meta name="screen-orientation" content="portrait"> // 強制橫屏 <meta name="screen-orientation" content="landscape"> // 應用模式 <meta name="browsermode" content="application">