摘要:前言本來是打算寫寫怎么使用進(jìn)行移動(dòng)端的布局的然后前面還加些像素基本知識(shí)鋪墊后面又加了些屬性概念最后還來些常見布局問題和系統(tǒng)樣式果然排版也是門高深學(xué)問這里有些自己寫的有些看完之后總結(jié)出來的還有些別人那里搬來的順帶會(huì)送上飛機(jī)票告訴你們來源在哪
前言
本來是打算寫寫怎么使用 lib-flexible 進(jìn)行移動(dòng)端的布局的, 然后前面還加些像素基本知識(shí)鋪墊, 后面又加了些 CSS 屬性概念, 最后還來些常見布局問題和系統(tǒng)樣式 bug, 果然排版也是門高深學(xué)問, 這里有些自己寫的, 有些看完之后總結(jié)出來的, 還有些別人那里搬來的, 順帶會(huì)送上飛機(jī)票告訴你們來源在哪里, 他們會(huì)更加仔細(xì), 畢竟我只是簡(jiǎn)明扼要的寫結(jié)論.
因?yàn)橹R(shí)點(diǎn)太多, 我沒有全都碰到過, 所以最后的一些樣式解決辦法是覺得有用寫出來的, 沒試過, 以后如果還有遇到其他問題或者看到別人有意思的方案也會(huì)補(bǔ)充進(jìn)來.
最后, 這文章我已經(jīng)轉(zhuǎn)成簡(jiǎn)體字了, 應(yīng)該不會(huì)再有人說看的吃力了吧.
疑問相比 PC 端, 移動(dòng)端怎么適配不同尺寸的屏幕?
為什么同一套代碼, 有些看起來很清晰, 有些看起來很模糊?
除了響應(yīng)式之外有一步到位的布局方法么?
為什么樣式?jīng)]寫錯(cuò), 有些手機(jī)用起來就是不正常?
怎么解決遇到的一些亂七八糟沒有邏輯的 bug?
像素基本知識(shí) 視窗 viewport:設(shè)備的屏幕上能用來顯示我們的網(wǎng)頁的那一塊區(qū)域, 而移動(dòng)端還提供了兩個(gè) viewport:
visual viewport(虛擬視口):
可以改變大小或形狀, 當(dāng)前屏幕上顯示的頁面的一部分
通過 window.innerWidth/Height 獲取, 會(huì)隨著頁面縮放而變化
layout viewport(布局視口):
不會(huì)改變大小或形狀, 可以比可視化的 viewport 寬得多, 并且包含出現(xiàn)在屏幕上的元素
通過 document.documentElement.clientWidth/Height 獲取. 在 Android 2, Oprea mini 和 UC 8 中無法正確獲取
ideal viewport(理想視口):不需要用戶縮放和滾動(dòng)就能正常的查看網(wǎng)站的所有內(nèi)容, 顯示的文字大小合適, 保證同樣的網(wǎng)站在不同分辨率的設(shè)備上看起來都是一樣或差不多的.
渲染過程:1) 渲染: 將整個(gè)頁面渲染在一個(gè) layout viewport 中, 以保證頁面排版正確;
2) 縮放: 將整個(gè) layout viewport 縮放到 visual viewport 大小, 以保證頁面在手機(jī)屏幕上被完整顯示出來;
公式表示就是: visual viewpor = layout viewport * scale;
例如你在手機(jī)上訪問一個(gè) PC 頁面, 手機(jī)當(dāng)前展示區(qū)域就是 visual viewport, 但是整個(gè) PC 頁面是很大的, 往往屏幕是顯示不完, 所以會(huì)出現(xiàn)滾動(dòng)條給你滑動(dòng)(固定值排版的話), 整個(gè) PC 頁面的尺寸就是 layout viewport 了, 上面說 visual viewport 可以改變大小或形狀, 意思是你可以通過旋轉(zhuǎn)屏幕或放大縮小改變顯示的頁面.
物理像素(physical pixel) || 設(shè)備像素:顯示設(shè)備中一個(gè)最微小的物理部件. 每個(gè)像素可以根據(jù)操作系統(tǒng)設(shè)置自己的顏色和亮度. 正是這些設(shè)備像素的微小距離欺騙了我們?nèi)庋劭吹降膱D像效果.
設(shè)備獨(dú)立像素(density-independent pixel) || 邏輯像素 || 密度無關(guān)像素:可以認(rèn)為是計(jì)算機(jī)坐標(biāo)系統(tǒng)中的一個(gè)點(diǎn), 這個(gè)點(diǎn)代表一個(gè)可以由程序使用并控制的虛擬像素(比如 CSS 像素), 然后由相關(guān)系統(tǒng)轉(zhuǎn)換為物理像素.
公式表示就是: CSS 像素 = 設(shè)備獨(dú)立像素 = 邏輯像素.
與設(shè)備無關(guān)的像素(device-independent pixel) || CSS 像素用于頁面布局的抽象單位, 用來精確度量網(wǎng)頁上的內(nèi)容, 在不同的設(shè)備或不同的環(huán)境中, css 中的 1px 所代表的設(shè)備物理像素的長(zhǎng)度可能是不同的
屏幕密度(pixels per inch) || 像素密度:即每英寸屏幕所擁有的像素?cái)?shù), 像素密度越大, 顯示畫面細(xì)節(jié)就越豐富,
公式表示就是: 像素密度 = 對(duì)角線分辨率 / 屏幕尺寸.
設(shè)備像素比(device pixel ratio):物理像素與邏輯像素之間的比例.
公式表示就是: 設(shè)備像素比(dpr) = 物理像素(pp) / 設(shè)備獨(dú)立像素(dip).
在 JavaScript 中, 可以通過 window.devicePixelRatio 獲取到當(dāng)前設(shè)備的 dpr. 而在 CSS 中, 可以通過 - webkit-device-pixel-ratio,-webkit-min-device-pixel-ratio 和 -webkit-max-device-pixel-ratio 進(jìn)行媒體查詢, 對(duì)不同 dpr 的設(shè)備, 做一些樣式適配
為什么需要了解這些?一切的起源來自于 iphone4 的誕生, 當(dāng)時(shí)它使用一種新的屏幕的顯示技術(shù) Retina(視網(wǎng)膜), 它將 640x960 的分辨率壓縮到一個(gè) 3.5 英寸的顯示屏, 像素密度達(dá)到 326 像素 / 英寸(ppi). 聲稱當(dāng)一個(gè)顯示屏像素密度超過 300ppi 時(shí), 人眼就無法區(qū)分出多帶帶的像素, 顯示設(shè)備清晰度已達(dá)到人視網(wǎng)膜可分辨像素的極限.
示例機(jī)型 | iPhone6S | 某某手機(jī) |
---|---|---|
設(shè)備寬高(pp) | 375 * 667 | 375 * 667 |
屏幕密度(ppi) | 326 | --- |
CSS 像素(px) | 375 * 667 | 375 * 667 |
設(shè)備獨(dú)立像素(dip) | 750dip * 1334dip | 375dip 667dip |
設(shè)備像素比(dpr) | 2 | 1 |
盡管兩者 CSS 像素所呈現(xiàn)的物理尺寸是一致的, 但在普通屏幕下 1 個(gè) CSS 像素對(duì)應(yīng) 1 個(gè)物理像素, 而在 Retina 屏幕下, 1 個(gè) CSS 像素對(duì)應(yīng)的卻是 4 個(gè)物理像素. 靠提升單位面積屏幕的像素?cái)?shù)量, 即像素密度來提升分辨率.
iphone 常見如下:
(更詳細(xì)內(nèi)容請(qǐng)看 The Ultimate Guide To iPhone Resolutions)
lib-flexible重點(diǎn)來了, 在舊的布局方式困難重重, 新的屬性方法短時(shí)間不被主流瀏覽器大范圍兼容的情況下, 手淘團(tuán)隊(duì)出了 lib-flexible.
基本原理先在 < html > 元素上增加一個(gè) data-dpr 屬性, 以及一個(gè) font-size 樣式. JS 會(huì)根據(jù)不同的設(shè)備添加不同的 data-dpr 值和對(duì)應(yīng)的 font-size 的值. 開發(fā)時(shí)候通過把設(shè)計(jì)稿做些計(jì)算轉(zhuǎn)換成 rem 單位來設(shè)置. 他們會(huì)根據(jù) html 元素的 font-size 值做相應(yīng)的計(jì)算, 從而實(shí)現(xiàn)屏幕的適配效果.
使用建議在頁面所有資源加載前執(zhí)行, 避免在渲染過程或之后再次重新計(jì)算樣式;
像字體, 某些固定尺寸的樣式可以直接使用 px;
(更詳細(xì)內(nèi)容請(qǐng)看使用 Flexible 實(shí)現(xiàn)手淘 H5 頁面的終端適配 https://www.w3cplus.com/mobil... )(還有一些常用的居中布局, 經(jīng)典布局方法和優(yōu)缺點(diǎn)可以參考我之前寫的文章頁面基礎(chǔ)布局相關(guān)知識(shí) --- 居中 & 經(jīng)典布局)
meta 標(biāo)簽這里只會(huì)列出一些常用的標(biāo)簽, 多帶帶某些瀏覽器或低版本系統(tǒng)不會(huì)列出來.
限制移動(dòng)端頁面視口寬度縮放等
移動(dòng)端必備標(biāo)簽!
屬性 | 描述 |
---|---|
width | device-width: viewport 寬度 |
initial-scale | 初始縮放比例 |
maximum-scale | 最大縮放比例 |
minimum-scale | 最小縮放比例 |
user-scalable | 是否允許用戶縮放(yes/no) |
很多時(shí)候真的只是文本文字, 也會(huì)被當(dāng)作電話號(hào)碼處理
忽略識(shí)別郵箱 刪除默認(rèn)的蘋果工具欄和菜單欄 設(shè)置蘋果狀態(tài)欄的背景顏色默認(rèn)值為default(白色),可以定為black(黑色)和black-translucent(黑色半透明.)
black-translucent 狀態(tài)欄背景是黑色半透明. 如果設(shè)置為 default 或 black , 網(wǎng)頁內(nèi)容從狀態(tài)欄底部開始. 如果設(shè)置為 black-translucent , 網(wǎng)頁內(nèi)容充滿整個(gè)屏幕, 頂部會(huì)被狀態(tài)欄遮擋.
蘋果添加到主屏后的標(biāo)題(iOS 6 新增) 蘋果是否啟用 WebApp 全屏模式 理論知識(shí) CSS 優(yōu)先級(jí)算法如何計(jì)算?元素選擇符: 1
class 選擇符: 10
id 選擇符: 100
內(nèi)聯(lián)樣式: 1000
!important 優(yōu)先級(jí)最高
如果優(yōu)先級(jí)相同, 則選擇最后出現(xiàn)的樣式;
繼承得到的樣式的優(yōu)先級(jí)最低;
嵌套選擇器優(yōu)先級(jí)是相加, 例如: #A .B = 100 + 10 = 110;
margin 有什么需要注意的特性?合并
margin 在垂直方向會(huì)合并, 其值為兩者最大值, 水平方向不合并;
如果元素內(nèi)容為空, 自身 margin 垂直方向也會(huì)合并, 其值為兩者最大值;
父元素如果沒有 padding, border 等屬性時(shí), 其子元素的 margin 上下方向會(huì)和父元素的 margin 進(jìn)行重疊;
與其他元素相交定位
位于普通文檔流中元素, 只會(huì)覆蓋顏色, 不會(huì)覆蓋文字;
relative 下, 會(huì)完全覆蓋前一個(gè)元素并影響后面元素一起移動(dòng);
absolute 下, 元素脫離了普通文檔流并對(duì)其他元素沒有影響;
對(duì)于 float 元素, 可以通過負(fù)值進(jìn)行覆蓋;
(原本想寫些例子, 但是太麻煩, 可能還得截圖標(biāo)注, 就干脆不寫了.)
為什么會(huì)出現(xiàn)浮動(dòng)和什么時(shí)候需要清除浮動(dòng)? 清除浮動(dòng)的方式?先說說 float 的特性:
浮動(dòng)元素會(huì)脫離正常文檔流, 一直平移到碰到容器邊框或者另一個(gè)浮動(dòng)元素;
浮動(dòng)元素會(huì)根據(jù)上一個(gè)元素的類型判斷位置:
如果是浮動(dòng)元素, 則跟隨他浮動(dòng), 放置不下就擠到下一行展示;
如果是標(biāo)準(zhǔn)流元素, 則浮動(dòng)元素的相對(duì)垂直高度不變, 頂部和上一個(gè)底部對(duì)齊;
浮動(dòng)帶來的問題:
父元素的高度無法被撐開, 影響與父元素同級(jí)的元素
與浮動(dòng)元素同級(jí)的非浮動(dòng)元素 (內(nèi)聯(lián)元素) 會(huì)跟隨其后
若非第一個(gè)元素浮動(dòng), 則該元素之前的元素也需要浮動(dòng), 否則會(huì)影響頁面顯示的結(jié)構(gòu).
綜合寫法:
.clearfix:after { content: ""; // 設(shè)置內(nèi)容為空 height: 0; // 高度為 0 line-height: 0; // 行高為 0 display: block; // 將文本轉(zhuǎn)為塊級(jí)元素 visibility: hidden; // 將元素隱藏 clear: both; // 清除浮動(dòng) } .clearfix { zoom: 1; // 為了兼容 IE; }position 跟 display,overflow,float 這些特性相互疊加后會(huì)怎么樣?
display 屬性規(guī)定元素應(yīng)該生成的框的類型;
overflow 屬性規(guī)定當(dāng)內(nèi)容溢出元素框時(shí)發(fā)生的事情.
position 屬性規(guī)定元素的定位類型;
float 屬性是一種布局方式, 定義元素在哪個(gè)方向浮動(dòng).
首先 overflow 怎么處理溢出顯示, 跟其他三者無沖突影響的;
如果 display: none 此元素不會(huì)被顯示. 否則就是規(guī)定元素應(yīng)該生成的框的類型;
如果脫離文檔流的話 position:absolute/fixed 優(yōu)先級(jí)高于浮動(dòng) float, 并且 display 只能影響子元素繼承屬性;
float 或者 absolute 定位的元素, display 只能是塊元素或表格;
元素豎向的百分比設(shè)定是相對(duì)于容器的高度嗎?當(dāng)按百分比設(shè)定一個(gè)元素的寬度時(shí), 它是相對(duì)于父容器的寬度計(jì)算的, 但是, 對(duì)于一些表示豎向距離的屬性, 例如 padding-top , padding-bottom , margin-top , margin-bottom 等, 當(dāng)按百分比設(shè)定它們時(shí), 依據(jù)的也是父容器的寬度, 而不是高度.
偽類和偽元素有哪些, 又有什么區(qū)別和作用?偽類 (Pseudo-classes) :active, :focus, :hover, :link, :visited, :first-child, :lang 等, 用于向某些選擇器添加特殊的效果.
偽元素 (Pseudo-elements) :first-letter, :first-line, :before, :after 等, 用于向某些選擇器設(shè)置特殊效果.
偽類能獲取不能被常規(guī) CSS 選擇器獲取的信息, 可以算是選擇器的一種補(bǔ)充吧, 每個(gè)選擇器可以同時(shí)使用多種偽類.
偽元素能在 DOM 樹中創(chuàng)建一些存在于文檔語言里的抽象元素.
對(duì) BFC 規(guī)范的理解?定義: BFC(Block formatting context)直譯為 "塊級(jí)格式化上下文". 它是一個(gè)獨(dú)立的渲染區(qū)域, 只有 Block-level box 參與, 它規(guī)定了內(nèi)部的 Block-level Box 如何布局, 并且與這個(gè)區(qū)域外部毫不相干.
w3c 規(guī)范中的 BFC 定義:
浮動(dòng)元素和絕對(duì)定位元素, 非塊級(jí)盒子的塊級(jí)容器(例如 inline-blocks, table-cells, 和 table-captions), 以及 overflow 值不為 "visiable" 的塊級(jí)盒子, 都會(huì)為他們的內(nèi)容創(chuàng)建新的 BFC(塊級(jí)格式上下文).
在 BFC 中, 盒子從頂端開始垂直地一個(gè)接一個(gè)地排列, 兩個(gè)盒子之間的垂直的間隙是由他們的 margin 值所決定的. 在一個(gè) BFC 中, 兩個(gè)相鄰的塊級(jí)盒子的垂直外邊距會(huì)產(chǎn)生折疊.
在 BFC 中, 每一個(gè)盒子的左外邊緣 (margin-left) 會(huì)觸碰到容器的左邊緣(border-left)(對(duì)于從右到左的格式來說, 則觸碰到右邊緣).
BFC 布局規(guī)則:
內(nèi)部的 Box 會(huì)在垂直方向, 一個(gè)接一個(gè)地放置;
Box 垂直方向的距離由 margin 決定. 屬于同一個(gè) BFC 的兩個(gè)相鄰 Box 的 margin 會(huì)發(fā)生重疊;
每個(gè)元素的 margin box 的左邊, 與包含塊 border box 的左邊相接觸(對(duì)于從左往右的格式化, 否則相反). 即使存在浮動(dòng)也是如此;
BFC 的區(qū)域不會(huì)與 float box 重疊;
BFC 就是頁面上的一個(gè)隔離的獨(dú)立容器, 容器里面的子元素不會(huì)影響到外面的元素. 反之也如此;
計(jì)算 BFC 的高度時(shí), 浮動(dòng)元素也參與計(jì)算;
觸發(fā)條件:
根元素, 即 html;
float 的值不為 none(默認(rèn));
overflow 的值不為 visible(默認(rèn));
display 的值為 inline-block,table-cell,table-caption;
position 的值為 absolute 或 fixed;
(更詳細(xì)內(nèi)容請(qǐng)看前端精選文摘: BFC 神奇背后的原理 )
層疊(實(shí)在復(fù)雜, 更詳細(xì)內(nèi)容請(qǐng)看 CSS 大神張?chǎng)涡竦纳钊肜斫?CSS 中的層疊上下文和層疊順序 , 下面都是我根據(jù)他的文章簡(jiǎn)要記錄下來的)
層疊上下文(stacking context): 是 HTML 中的一個(gè)三維的概念. 如果一個(gè)元素含有層疊上下文, 我們可以理解為這個(gè)元素在 z 軸上就 "高人一等".
層疊水平(stacking level): 決定了同一個(gè)層疊上下文中元素在 z 軸上的顯示順序.
層疊順序(stacking order): 表示元素發(fā)生層疊時(shí)候有著特定的垂直顯示順序.
注意: 上面的層疊上下文和層疊水平是概念, 而這里的層疊順序是規(guī)則.
(原諒我盜圖)
普通元素的層疊水平優(yōu)先由層疊上下文決定, 某些情況下 z-index 可以影響層疊水平, 但是, 只限于定位元素以及 flex 盒子的子元素;
當(dāng)在同一個(gè)層疊上下文領(lǐng)域具有明顯的層疊水平標(biāo)示的時(shí)候, 如 z-indx, 層疊水平值大的那一個(gè)覆蓋小的那一個(gè);
當(dāng)元素的層疊水平一致, 層疊順序相同的時(shí)候, 在 DOM 流中處于后面的元素會(huì)覆蓋前面的元素;
層疊上下文的層疊水平要比普通元素高;
層疊上下文可以阻斷元素的混合模式(普通元素的層疊水平優(yōu)先由層疊上下文決定);
層疊上下文可以嵌套, 內(nèi)部層疊上下文及其所有子元素均受制于外部的層疊上下文(父元素的層級(jí)決定了子元素之間的層級(jí)比較);
每個(gè)層疊上下文和兄弟元素獨(dú)立, 也就是當(dāng)進(jìn)行層疊變化或渲染的時(shí)候, 只需要考慮后代元素;
每個(gè)層疊上下文是自成體系的, 當(dāng)元素發(fā)生層疊的時(shí)候, 整個(gè)元素被認(rèn)為是在父層疊上下文的層疊順序中;
根層疊上下文:
頁面根元素 html;
定位元素與傳統(tǒng)層疊上下文:
對(duì)于包含有 position:relative/position:absolute 的定位元素, 以及 FireFox/IE 瀏覽器 (不包括 Chrome 等 webkit 內(nèi)核瀏覽器) 下含有 position:fixed 聲明的定位元素, 當(dāng)其 z-index 值不是 auto 的時(shí)候, 會(huì)創(chuàng)建層疊上下文;
CSS3 與新時(shí)代的層疊上下文:
z-index 值不為 auto 的 flex 項(xiàng)(父元素 display:flex|inline-flex).
元素的 opacity 值不是 1.
元素的 transform 值不是 none.
元素 mix-blend-mode 值不是 normal.
元素的 filter 值不是 none.
元素的 isolation 值是 isolate.
will-change 指定的屬性值為上面任意一個(gè).
元素的 - webkit-overflow-scrolling 設(shè)為 touch.
層疊上下文之間的順序:
如果不依賴 z-index, 則 z-index:auto 可看成 z:index:0 級(jí)別;
元素一旦成為定位元素, 其 z-index 就會(huì)自動(dòng)生效就是默認(rèn)的 auto, 也就是 0 級(jí)別, 根據(jù)上面的層疊順序表, 就會(huì)覆蓋 inline 或 block 或 float 元素;
不支持 z-index 的層疊上下文元素天然 z-index:auto 級(jí)別, 也就意味著, 層疊上下文元素和定位元素是一個(gè)層疊順序的, 遵循的是 "后來居上" 準(zhǔn)則
如果依賴 z-index, 則其層疊順序由 z-index 值決定.
z-index 勝者為王;
瀏覽器是怎樣解析 CSS 選擇器的?.title {} .title h1 {} .title h1 span {}
要找到. title .h1 span 選擇器:
找到父節(jié)點(diǎn) title;
在父節(jié)點(diǎn)之下找 h1;
再找到 h1 下面的 span;
看起來順利解析完畢, 然后來看看再看看稍微復(fù)雜點(diǎn)的
.title {} .title h1 {} .title h2 {} .title h1 em {} .title h1 span {}
要找到. title .h1 span 選擇器:
找到父節(jié)點(diǎn) title;
在父節(jié)點(diǎn)之下找 h1(第三行不符合);
再找到 h1 下面的 span(第四行不符合);
在這里也能大概看得出, 如果是從左往右解析 CSS 選擇器的話, 每次發(fā)現(xiàn)不符合規(guī)則的都要進(jìn)行回溯, 不僅浪費(fèi)時(shí)間而且浪費(fèi)性能, 所以上面的說法是我誤導(dǎo)不懂的人的, 實(shí)際上瀏覽器 CSS 選擇器的解析規(guī)則是從右往左的. 然后我們?cè)倏纯瓷厦娴慕馕鲆?guī)則.
找到子節(jié)點(diǎn) span;
在 span 的父節(jié)點(diǎn)上找 h1;
在 h1 的父節(jié)點(diǎn)上找 title;
整個(gè)解析下來, 每一步都能過濾掉些不符合規(guī)則的分支情況, 直到找到根元素或滿足條件的匹配規(guī)則的選擇器就結(jié)束這個(gè)分支的遍歷.
最后建議:, 不管瀏覽器怎么解析, 我剛開始學(xué)前端的時(shí)候就經(jīng)??吹侥敲匆痪湓? 盡量避免深層嵌套 CSS, 因?yàn)閷ふ疫x擇器和計(jì)算最終樣式都會(huì)受影響的.
如果需要手動(dòng)寫動(dòng)畫, 你認(rèn)為最小時(shí)間間隔是多久, 為什么?多數(shù)顯示器默認(rèn)頻率是 60Hz, 即 1 秒刷新 60 次, 所以理論上最小間隔為 1/60*1000ms = 16.7ms.
移動(dòng)端點(diǎn)擊 300ms 延遲原因: 因?yàn)槭謾C(jī)會(huì)通過 300ms 的延遲判斷用戶是單擊還是雙擊屏幕決定執(zhí)行哪種手勢(shì)行為.
解決方案:
網(wǎng)頁頭部 meta 標(biāo)簽禁用縮放, 為了解決短暫的延遲問題卻要完全禁止用戶手勢(shì)縮放行為, 這就過分了;
網(wǎng)頁頭部 meta 標(biāo)簽設(shè)置視口寬度為設(shè)備寬度, 優(yōu)點(diǎn)是只禁用雙擊手勢(shì)縮放功能;
指針事件, 是一個(gè)新的 web 事件系列, 相應(yīng)的規(guī)范旨在使用一個(gè)多帶帶的事件模型, 對(duì)所有輸入類型, 包括鼠標(biāo) (mouse), 觸摸 (touch), 觸控 (stylus) 等, 進(jìn)行統(tǒng)一的處理. 其中 touch-action
屬性決定 "是否觸摸操作會(huì)觸發(fā)用戶代理的默認(rèn)行為. 這包括但不限于雙指縮放等行為". 但瀏覽器兼容是個(gè)問題;
解決庫:
指針事件庫, 就是上面第三個(gè)方案的 js 兼容庫;
FastClick.js , 實(shí)現(xiàn)原理是在檢測(cè)到 touchend 事件的時(shí)候, 會(huì)通過 DOM 自定義事件立即觸發(fā)模擬一個(gè) click 事件, 并把瀏覽器在 300ms 之后的 click 事件阻止掉. 需要注意的是至 2015 年之后的瀏覽器大多數(shù)都已經(jīng)取消了 300ms 的延遲, 再引入的話不僅沒用還可能引起應(yīng)用 bug;
tap 事件代替 click, 如果你引用的庫或框架有提供的話;
(我發(fā)現(xiàn)有個(gè)文章深入源碼分析的挺好的, 雖然我沒細(xì)看, 有興趣可以看一下[[讀 fastclick 源碼有感] 徹底解決 tap"點(diǎn)透", 提升移動(dòng)端點(diǎn)擊響應(yīng)速度](https://github.com/ftlabs/fas... )
點(diǎn)擊穿透問題原因: 移動(dòng)端一次點(diǎn)擊會(huì)順序觸發(fā) touchstart -> touchmove -> touchend -> tap(如果有) -> click, 并且 click 有 300ms 的滯后性.
舉例: 有一對(duì)父子元素, 分別綁定讓自身消失的事件在父元素的 click 和子元素的 touchstart 上, 當(dāng)點(diǎn)擊子元素會(huì)讓子元素自身消失, 過了 300ms 之后才會(huì)觸發(fā)到 click 事件, 但是子元素已經(jīng)消失了, click 事件會(huì)被順遞派發(fā)到下層的父元素讓其也消失.
解決方案:
盡量都使用 touch 事件來替換 click 事件. 例如用 touchend 事件(推薦);
fastclick;
preventDefault 阻止;
延遲一定的時(shí)間 (300ms+) 來處理事件 (不推薦);
以上一般都能解決, 實(shí)在不行就換成 click 事件;
滾動(dòng)穿透問題舉例: 當(dāng)頁面彈出遮罩的時(shí)候依然可以讓頁面滾動(dòng).
解決方案:
touchmove 事件監(jiān)聽加 e.preventDefault()
如果遮罩本身也有滾動(dòng)條也會(huì)被禁止;
body/html 添加 overflow:hidden,height: 100%;
部分機(jī)器 / 瀏覽器不行;
頁面的背景還是能夠有滾的動(dòng)的效果;
滾動(dòng)位置消失, 需要 js 計(jì)算修復(fù);
body.modal-open {position: fixed; width: 100%;} ------------------------------------------------------------ var ModalHelper = (function(bodyCls) { var scrollTop; // 在閉包中定義一個(gè)用來保存滾動(dòng)位置的變量 return { afterOpen: function() { // 彈出之后記錄保存滾動(dòng)位置, 并且給 body 添加. modal-open scrollTop = document.scrollingElement.scrollTop; document.body.classList.add(bodyCls); document.body.style.top = -scrollTop + "px"; }, beforeClose: function() { // 關(guān)閉時(shí)將. modal-open 移除并還原之前保存滾動(dòng)位置 document.body.classList.remove(bodyCls); document.scrollingElement.scrollTop = scrollTop; }, }; })("modal-open");
(從網(wǎng)上看到的方法關(guān)于移動(dòng)端開發(fā)中遇到的坑)
通用樣式這里只會(huì)總結(jié)部分特殊問題, 太常見的就不提, IE 的不提, 低版本瀏覽器問題不提(主要我也不懂).
改變輸入框 placeholder 的顏色值::-webkit-input-placeholder { /* WebKit browsers */ color: #999; } :-moz-placeholder { /* Mozilla Firefox 4 to 18 */ color: #999; } ::-moz-placeholder { /* Mozilla Firefox 19+ */ color: #999; } :-ms-input-placeholder { /* Internet Explorer 10+ */ color: #999; } input:focus::-webkit-input-placeholder { color: #999; }省略文本
單行文本
p{ overflow: hidden;/*超出部分隱藏*/ text-overflow:ellipsis;/* 超出部分顯示省略號(hào) */ white-space: nowrap;/*規(guī)定段落中的文本不進(jìn)行換行 */ width: 250px;/*需要配合寬度來使用*/ border: 1px solid red; font-size: 30px; }
多行文本
p{ display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; width: 250px; border: 1px solid red; font-size: 30px; }旋轉(zhuǎn)樣式
// 豎屏?xí)r樣式 @media all and (orientation:portrait){} // 橫屏?xí)r樣式 @media all and (orientation:landscape){}transition 閃屏
//設(shè)置內(nèi)嵌的元素在 3D 空間如何呈現(xiàn): 保留 3D -webkit-transform-style: preserve-3d; //設(shè)置進(jìn)行轉(zhuǎn)換的元素的背面在面對(duì)用戶時(shí)是否可見: 隱藏 -webkit-backface-visibility:hidden; //定義 3D 元素距視圖的距離,以像素計(jì) -webkit-perspective: 1000;純 CSS 創(chuàng)建三角形?
div { width: 0; height: 0; border-top: 40px solid transparent; border-left: 40px solid transparent; border-right: 40px solid transparent; border-bottom: 40px solid #ff0000; }input[type=number]的問題
1, maxlength 屬性不會(huì)提供任何反饋.
用 js 解決
2, form 提交會(huì)默認(rèn)取整數(shù).
step 屬性規(guī)定 < input > 元素的合法數(shù)字間隔, 也是通過自帶箭頭增減的數(shù)字, 默認(rèn)為 1
通過 transform 進(jìn)行 skew 變形, rotate 旋轉(zhuǎn)會(huì)造成出現(xiàn)鋸齒現(xiàn)象Element { -webkit-transform: rotate(-4deg) skew(10deg) translateZ(0); transform: rotate(-4deg) skew(10deg) translateZ(0); outline: 1px solid rgba(255,255,255,0); }打電話
打電話給: 10086發(fā)短信, winphone 系統(tǒng)無效
發(fā)短信給: 10086寫郵件
第一個(gè)功能以 "?" 開頭, 后面的以 "&" 開頭
mailto: 普通郵件
cc: 收件地址后添加抄送地址(Android 存在兼容問題)
bcc: 抄送地址后添加密件抄送地址(Android 存在兼容問題)
subject: 包含主題
body: 包含內(nèi)容,
如包含文本, 使用 給文本換行
如包含 http(s):// 等的文本自動(dòng)轉(zhuǎn)化為鏈接
如內(nèi)容包含圖片(PC 不支持)
包含多個(gè)收件人, 抄送, 密件抄送人, 用分號(hào) (;) 隔開多個(gè)郵件人的地址
點(diǎn)擊我發(fā)郵件系統(tǒng)兼容問題
安卓蘋果常見的問題, 還有些基于系統(tǒng)版本, 瀏覽器版本的不說.
某些 Android 手機(jī)圓角失效Element { background-clip: padding-box; }android 去掉語音輸入按鈕
input::-webkit-input-speech-button {display: none}ios 和 android 下觸摸元素時(shí)出現(xiàn)半透明灰色遮罩
Element { -webkit-tap-highlight-color: rgba(255,255,255,0); }
有些機(jī)型去除不了, 不使用 a 或者 input 標(biāo)簽, 直接用 div 標(biāo)簽
ios 設(shè)置 input 按鈕樣式會(huì)被默認(rèn)樣式覆蓋input, textarea { border: 0; -webkit-appearance: none; }iphone 及 ipad 下輸入框默認(rèn)內(nèi)陰影
Element { -webkit-appearance: none; }Retina 屏的 1px 邊框
Element { border-width: thin; }關(guān)于 iOS 系統(tǒng)中, 中文輸入法輸入英文時(shí), 字母之間可能會(huì)出現(xiàn)一個(gè)六分之一空格
this.value = this.value.replace(/u2006/g, "");IOS 中 input 鍵盤事件 keyup,keydown,keypress 支持不是很好
html5 的 oninput 事件代替
iOS 某些時(shí)候會(huì)覺得滾動(dòng)很卡Element { -webkit-overflow-scrolling: touch; }
auto: 使用普通滾動(dòng), 當(dāng)手指從觸摸屏上移開, 滾動(dòng)會(huì)立即停止.
touch: 使用具有回彈效果的滾動(dòng), 當(dāng)手指從觸摸屏上移開, 內(nèi)容會(huì)繼續(xù)保持一段時(shí)間的滾動(dòng)效果. 繼續(xù)滾動(dòng)的速度和持續(xù)的時(shí)間和滾動(dòng)手勢(shì)的強(qiáng)烈程度成正比. 同時(shí)也會(huì)創(chuàng)建一個(gè)新的堆棧上下文.
啟動(dòng)了硬件加速的特性, 所以滑動(dòng)起來會(huì)非常流暢; 不過會(huì)影響性能
解決 IOS 鍵盤字母輸入默認(rèn)首字母大寫 禁止長(zhǎng)按鏈接與圖片彈出菜單a, img { -webkit-touch-callout: none; }手機(jī)拍照和上傳圖片
IOS 有拍照, 錄像, 選取本地圖片功能, 部分 Android 只有選擇本地圖片功能. Winphone 不支持
輸入框被鍵盤擋住問題
if (/Android/.test(navigator.appVersion)) { window.addEventListener("resize", function() { if (document.activeElement.tagName == "INPUT" || document.activeElement.tagName == "TEXTAREA") { document.activeElement.scrollIntoView(); } }); }
可以解決絕大數(shù)安卓機(jī)上面的問題
播放視頻不全屏ios7 + 支持自動(dòng)播放
支持 Airplay 的設(shè)備 (如: 音箱, Apple TV) 播放: x-webkit-airplay="true"
播放視頻不全屏: webkit-playsinline="true"
移動(dòng)端 HTML5 audio autoplay 失效問題蘋果系統(tǒng)和安卓系統(tǒng)通常都會(huì)禁止自動(dòng)播放和使用 JS 的觸發(fā)播放, 必須由用戶來觸發(fā)才可以播放.
audio 元素的 autoplay 屬性在 IOS 及 Android 上無法使用, 在 PC 端正常
audio 元素沒有設(shè)置 controls 時(shí), 在 IOS 及 Android 會(huì)占據(jù)空間大小, 而在 PC 端 Chrome 是不會(huì)占據(jù)任何空間
解決方法思路: 先通過用戶 touchstart 觸碰, 觸發(fā)播放并暫停(音頻開始加載, 后面用 JS 再操作就沒問題了).
document.addEventListener("touchstart", function() { document.getElementsByTagName("audio")[0].play(); document.getElementsByTagName("audio")[0].pause(); });
微信下兼容處理
document.addEventListener( "WeixinJSBridgeReady", function() { music.play(); }, false );
ios10 + 以上, 盡管開發(fā)者設(shè)置了 user-scalable=no,Safari 還是允許用戶通過手勢(shì)來縮放
檢測(cè) touch 相關(guān)事件來阻止事件的觸發(fā)
window.onload = function () { // 同時(shí)按下兩個(gè)手指 document.addEventListener("touchstart", function (event) { if (event.touches.length > 1) { event.preventDefault(); } }); var lastTouchEnd = 0; // 特別注意 300ms 時(shí)差的設(shè)置 document.addEventListener("touchend", function (event) { var now = new Date().getTime(); if (now - lastTouchEnd <= 300) { event.preventDefault(); } lastTouchEnd = now; }); };定位的坑
fixed 定位
ios 下 fixed 元素容易定位出錯(cuò), 軟鍵盤彈出時(shí), 影響 fixed 元素定位
android 下 fixed 表現(xiàn)要比 iOS 更好, 軟鍵盤彈出時(shí), 不會(huì)影響 fixed 元素定位
ios4 下不支持 position:fixed
解決方案: 使用 Iscroll , 如:
position 定位
Android 下彈出軟鍵盤彈出時(shí), 影響 absolute 元素定位
var ua = navigator.userAgent.indexOf("Android"); if (ua > -1) { $(".ipt") .on("focus", function() { $(".css").css({ visibility: "hidden" }); }) .on("blur", function() { $(".css").css({ visibility: "visible" }); }); }各種黑科技
使用的都是些特殊屬性, 兼容性是個(gè)比較大的問題.
Chrome 設(shè)置小于 12px 的字體大小?新版本谷歌好像取消支持了
-webkit-text-size-adjust: none;
縮小尺寸
-webkit-transform: scale(0.5);
解決縮放后 margin-left 的位移問題
-webkit-transform-origin-x: 0;
解決縮放后 margin-left 的位移問題
-webkit-transform-origin-x: 0;
注意: 放在 body 上會(huì)導(dǎo)致頁面縮放失效
長(zhǎng)時(shí)間按住頁面出現(xiàn)閃退element { -webkit-touch-callout: none; }旋轉(zhuǎn)屏幕時(shí), 字體大小調(diào)整的問題
body, div, fieldset, form, h1, h2, h3, h4, h5, h6, html, p { webkit-text-size-adjust: 100%; }去除 input 默認(rèn)樣式
input[type=number] { -moz-appearance: textfield; } input[type=number]::-webkit-inner-spin-button, input[type=number]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }禁用 radio 和 checkbox 默認(rèn)樣式,::-ms-check 修改表單復(fù)選框或單選框默認(rèn)圖標(biāo), 設(shè)置隱藏并使用背景圖片來修飾
input[type=checkbox]::-ms-check, input[type=radio]::-ms-check { display: none; }禁用 pc 端表單輸入框默認(rèn)清除按鈕,::-ms-clear 修改清除按鈕, 設(shè)置隱藏并使用背景圖片來修飾
input[type=number]::-ms-clear, input[type=tel]::-ms-clear, input[type=text]::-ms-clear { display: none; }select 下拉選擇設(shè)置右對(duì)齊
select option { direction: rtl; }出現(xiàn)滾動(dòng)條時(shí)頁面跳動(dòng)?
原因是滾動(dòng)條占據(jù)一定的寬度擠壓了頁面布局導(dǎo)致的.
Element { margin-left: calc(100vw - 100%); }禁止復(fù)制, 選中文本
Element { -webkit-user-select: none; -moz-user-select: none; -khtml-user-select: none; user-select: none; }
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/116175.html
摘要:前言本來是打算寫寫怎么使用進(jìn)行移動(dòng)端的布局的然后前面還加些像素基本知識(shí)鋪墊后面又加了些屬性概念最后還來些常見布局問題和系統(tǒng)樣式果然排版也是門高深學(xué)問這里有些自己寫的有些看完之后總結(jié)出來的還有些別人那里搬來的順帶會(huì)送上飛機(jī)票告訴你們來源在哪 前言 本來是打算寫寫怎么使用 lib-flexible 進(jìn)行移動(dòng)端的布局的, 然后前面還加些像素基本知識(shí)鋪墊, 后面又加了些 CSS 屬性概念, 最...
摘要:為此決定自研一個(gè)富文本編輯器。例如當(dāng)要轉(zhuǎn)化的對(duì)象有環(huán)存在時(shí)子節(jié)點(diǎn)屬性賦值了父節(jié)點(diǎn)的引用,為了關(guān)于函數(shù)式編程的思考作者李英杰,美團(tuán)金融前端團(tuán)隊(duì)成員。只有正確使用作用域,才能使用優(yōu)秀的設(shè)計(jì)模式,幫助你規(guī)避副作用。 JavaScript 專題之惰性函數(shù) JavaScript 專題系列第十五篇,講解惰性函數(shù) 需求 我們現(xiàn)在需要寫一個(gè) foo 函數(shù),這個(gè)函數(shù)返回首次調(diào)用時(shí)的 Date 對(duì)象,注意...
摘要:實(shí)戰(zhàn)之微信錢包騰訊服務(wù)界面網(wǎng)格布局是讓開發(fā)人員設(shè)計(jì)一個(gè)網(wǎng)格并將內(nèi)容放在這些網(wǎng)格內(nèi)。對(duì)于移動(dòng)端適配,不同的公司不同的團(tuán)隊(duì)有不同的解決方案。柵格系統(tǒng)用于處理頁面多終端適配的問題。 grid實(shí)戰(zhàn)之微信錢包 騰訊服務(wù)界面 CSS3網(wǎng)格布局是讓開發(fā)人員設(shè)計(jì)一個(gè)網(wǎng)格并將內(nèi)容放在這些網(wǎng)格內(nèi)。而不是使用浮動(dòng)制作一個(gè)網(wǎng)格,實(shí)際上是你將一個(gè)元素聲明為一個(gè)網(wǎng)格容器,并把元素內(nèi)容置于網(wǎng)格中。 移動(dòng)端頁面適配—...
閱讀 2959·2021-09-10 10:51
閱讀 2292·2021-09-02 15:21
閱讀 3279·2019-08-30 15:44
閱讀 957·2019-08-29 18:34
閱讀 1732·2019-08-29 13:15
閱讀 3389·2019-08-26 11:37
閱讀 2761·2019-08-26 10:46
閱讀 1168·2019-08-26 10:26