【每日一題NO.64】移動(dòng)端適配方案具體實(shí)現(xiàn)及對(duì)比

方案有以下幾種:
Media Queris
flex 彈性布局
rem + viewport 縮放
純 VW 方案
vw + rem 方案
百分比
Media Queris
media queris 的方式可以說是早期采用的布局方式,主要是通過查詢?cè)O(shè)備的寬度來執(zhí)行不同的 css 代碼,最終達(dá)到界面的配置。
核心語法:
@media?only?screen?and?(max-width:?374px)?{
??/*?iphone5?或者更小的尺寸,以?iphone5?的寬度(320px)比例設(shè)置樣式*/
}
@media?only?screen?and?(min-width:?375px)?and?(max-width:?413px)?{
??/*?iphone6/7/8?和?iphone?x?*/
}
@media?only?screen?and?(min-width:?414px)?{
??/*?iphone6p?或者更大的尺寸,以?iphone6p?的寬度(414px)比例設(shè)置樣式?*/
}
優(yōu)點(diǎn):
media query 可以做到設(shè)備像素比的判斷,方法簡(jiǎn)單,成本低,特別是針對(duì)移動(dòng)端和 pc 端維護(hù)同一套代碼的時(shí)候。目前像 Bootstrap 等框架使用這種方式布局。
圖片便于修改,只需要修改 css 文件。
調(diào)整屏幕寬度的時(shí)候不用刷新頁面即可響應(yīng)式展示
缺點(diǎn):
代碼量比較大,維護(hù)不方便
為了兼顧大屏幕或高清設(shè)備,會(huì)造成其他設(shè)備資源浪費(fèi),特別是加載圖片資源
為了兼顧移動(dòng)端和 pc 端各自響應(yīng)式的展示效果,難免會(huì)損失各自特有的交互方式
flex 彈性布局
高度固定、寬度自適應(yīng),元素都采用 px 做單位。
隨著屏幕寬度變化,頁面也會(huì)跟著變化,效果和 pc 頁面的流體布局差不多,在哪個(gè)寬度需要調(diào)整的時(shí)候使用響應(yīng)式布局調(diào)調(diào)就行,這樣就實(shí)現(xiàn)了適配。
rem + viewport 縮放
rem 是相對(duì)長(zhǎng)度單位,rem 方案中的樣式設(shè)計(jì)相對(duì)于根元素 font-size計(jì)算值的倍數(shù)。
根據(jù)屏幕寬度設(shè)置 html 標(biāo)簽的font-size,在布局的時(shí)候使用 rem 單位布局,達(dá)到自適應(yīng)的目的。
通過以下代碼來控制 rem 基準(zhǔn)值(設(shè)計(jì)稿以 720px 寬度量取實(shí)際尺寸)
!(function?(d)?{
??var?c?=?d.document;
??var?a?=?c.documentElement;
??var?b?=?d.devicePixelRatio;
??var?f;
??function?e()?{
????var?h?=?a.getBoundingClientRect().width,
??????g;
????if?(b?===?1)?{
??????h?=?720;
????}
????if?(h?>?720)?h?=?720;?//設(shè)置基準(zhǔn)值的極限值
????g?=?h?/?7.2;
????a.style.fontSize?=?g?+?"px";
??}
??if?(b?>?2)?{
????b?=?3;
??}?else?{
????if?(b?>?1)?{
??????b?=?2;
????}?else?{
??????b?=?1;
????}
??}
??a.setAttribute("data-dpr",?b);
??d.addEventListener(
????"resize",
????function?()?{
??????clearTimeout(f);
??????f?=?setTimeout(e,?200);
????},
????false
??);
??e();
})(window);
css 通過 sass 預(yù)編譯。設(shè)置量取的 px 值轉(zhuǎn)化 rem 的變量
$px:?(1/100)?+?rem;
優(yōu)點(diǎn):
兼容性好,頁面不會(huì)因?yàn)樯炜s發(fā)生變形,自適應(yīng)效果更佳
缺點(diǎn):
不是純 css 移動(dòng)適配方案,需要在頭部?jī)?nèi)嵌一段 js 腳本監(jiān)聽分辨率的變化來動(dòng)態(tài)改變根元素的字體大小,css 樣式和 js 代碼有一定的耦合性,并且必須將改變 font-size 的代碼放在 css 樣式之前。
小數(shù)像素問題,瀏覽器渲染最小的單位是像素,元素根據(jù)屏幕寬度自適應(yīng),通過 rem 計(jì)算后可能出現(xiàn)小數(shù)像素,瀏覽器會(huì)對(duì)這部分小數(shù)四舍五入,按照整數(shù)渲染,有可能計(jì)算沒有那么準(zhǔn)確
純 VW 方案
視口是瀏覽器中用于呈現(xiàn)網(wǎng)頁的區(qū)域。vw:1vw 等于視口寬度的 1%vh:1vh 等于視口高度的 1%vmin:選取 vw 和 vh 中最小的那個(gè)vmax:選取 vw 和 vh 中最大的那個(gè)
雖然 vw 能更優(yōu)雅的適配,但是還是有點(diǎn)小問題,就是寬高沒法限制。
$base_vw?=?375;
@function?vw($px)?{
??return?($px/$base_vw)?*?100vw
};
優(yōu)點(diǎn):
純 css 移動(dòng)端適配方案,不存在腳本依賴問題。
相對(duì)于 rem 以根元素字體大小的倍數(shù)定義元素大小,邏輯清晰簡(jiǎn)單
缺點(diǎn):
存在一些兼容性問題,有些瀏覽器不支持
vw + rem 方案
/*?設(shè)置html根元素的大小?750px->75?640px->64
/?將屏幕分成10份,每份作為根元素的大小。?*/
$vw_fontsize:?75?@function?rem($px)?{
??/*?例如:一個(gè)div的寬度為100px,那么它對(duì)應(yīng)的rem單位就是?(100/根元素的大小)*1rem */
??@return?($px?/?$vw_fontsize)?*?1rem;
}
$base_design:?750?
html?{
??/*?rem與vw相關(guān)聯(lián)?*/
??font-size:?($vw_fontsize?/?($base_design?/?2))?*?100vw;
??/*?同時(shí),通過Media?Queries?限制根元素最大最小值?*/
??@media?screen?and?(max-width:?320px)?{
????font-size:?64px;
??}
??@media?screen?and?(min-width:?540px)?{
????font-size:?108px;
??}
}
/*?body?也增加最大最小寬度限制,避免默認(rèn)100%寬度的?block?元素跟隨?body?而過大過小?*/
body?{
??max-width:?540px;
??min-width:?320px;
}
百分比
使用百分比定義寬度、高度用 px 固定,根據(jù)可視區(qū)域?qū)崟r(shí)尺寸進(jìn)行調(diào)整,盡可能適應(yīng)各種分辨率,通常使用max-width、min-width控制尺寸范圍過大或者過小。
優(yōu)點(diǎn):
原理簡(jiǎn)單,不存在兼容性問題
缺點(diǎn):
如果屏幕尺度跨度太大,相對(duì)設(shè)計(jì)稿過大或者過小的屏幕不能正常顯示。在大屏手機(jī)或豎屏切換場(chǎng)景下可能會(huì)導(dǎo)致頁面元素被拉伸變形,字體大小無法隨屏幕大小發(fā)生變化。
設(shè)置盒模型的不同屬性時(shí),其百分比設(shè)置的參考元素不唯一,容易使布局問題變得復(fù)雜。
所有《每日一題》的 知識(shí)大綱索引腦圖 整理在此:https://www.yuque.com/dfe_evernote/interview/everyday
你也可以點(diǎn)擊文末的 “閱讀原文” 快速跳轉(zhuǎn)

