前言
大家好,我是林三心,用最通俗易懂的話講最難的知識點是我的座右銘,基礎是進階的前提是我的初心~
分享一篇移動端適配的多個方案,也可以說說你是怎麽做的。
正文
自適應:根據不同的裝置螢幕大小來自動調整尺寸、大小
響應式:會隨著螢幕的即時變動而自動調整,是一種更強的自適應
為什麽要做移動端適配?
目前市面上移動端螢幕尺寸非常的繁多,很多時候我們希望一個元素在不同的螢幕上顯示不同的大小以此來更好的還原效果圖:
當我們針對一個手機進行布局設計時,設定了一個 200 * 200 大小的盒子
但在不同的裝置上,由於邏輯像素不同的問題,會使得這個盒子在更大的視口上顯得很小,在更小的視口上顯示很大
因此我們需要進行適配 讓它在不同裝置上所占據視口的空間比例是相同的
當前流行的幾種適配方案
方案一:百分比設定(不推薦)
因為不同內容的百分比值,相對的可能是不同參照物,所以百分比往往很難統一
所以百分比在移動端適配中使用是非常少的
方案二:rem單位+動態html的font-size
方案三:vw單位(推薦)
方案四:flex的彈性布局
rem + 動態設定 font-size
rem 單位是相對於 html 元素的 font-size 來設定的,透過在不同螢幕尺寸下,動態的修改 html 元素的 font-size 以此來達到適配效果
在開發中,我們只需要考慮兩個問題:
針對不同的螢幕,設定 html 不同的 font-size
將原來設定的尺寸,轉化成 rem 單位
font-size 的尺寸
螢幕尺寸 | html的font-size | 盒子的設定寬度 | 盒子的最終寬度 |
---|---|---|---|
375px | 37.5px | 1rem | 37.5px |
320px | 32px | 1rem | 32px |
414px | 41.4px | 1rem | 41.4px |
px 與 rem 的單位換算
手動換算
根元素 html 的文字大小 = 視口寬度/分成的份數(一般為10份,方便計算)
rem 值 = 元素的 px 值 / 根元素 html 的文字大小
比如有一個在375px螢幕上,100px寬度和高度的盒子
我們需要將100px轉成對應的rem值
100/37.5=2.6667,其他也是相同的方法計算即可
less/scss函式
.pxToRem(@px) {
result: 1rem * (@px / 37.5);
}
.box {
width: .pxToRem(100)[result];
height: .pxToRem(100)[result];
background-color: orange;
}
p {
font-size: .pxToRem(14)[result];
}
postcss-pxtorem
目前在前端的工程化開發中,我們可以借助於webpack的工具來完成自動的轉化
npm install postcss-pxtorem
VSCode外掛程式
方案一:媒體查詢
思路:透過媒體查詢來設定不同尺寸螢幕下 html 的 font-size
缺點:
需要針對不同的螢幕編寫大量的媒體查詢
如果動態改變尺寸,不會即時更新,只是一個個區間
@media screen and (min-width: 320px) {
html {
font-size: 20px;
}
}
@media screen and (min-width: 375px) {
html {
font-size: 24px;
}
}
@media screen and (min-width: 414px) {
html {
font-size: 28px;
}
}
@media screen and (min-width: 480px) {
html {
font-size: 32px;
}
}
.box {
width: 5rem;
height: 5rem;
background-color: blue;
}
方案二:編寫 js 程式碼
思路:透過監聽螢幕尺寸的變化來動態修改 html 元素的 font-size 大小
方法:
根據 html 的寬度計算出 font-size 的大小,並設定到 html 上
監聽頁面尺寸的變化,即時修改 font-size 大小
functionsetRemUnit() {
// 獲取所有的 html 元素
const htmlEl = document.documentElement
// 375 -> 16px
// 320px -> 12px
// 我們需要動態更改字型大小,因此需要獲取網頁的寬度
// 拿到客戶端寬度
const htmlWidth = htmlEl.clientWidth
// 將寬度分成10份
const htmlFontSize = htmlWidth / 10
console.log('htmlFontSize', htmlFontSize);
// 將值給到html的font-size
htmlEl. style.fontSize = htmlFontSize + 'px'
}
setRemUnit()
// 給 window 添加監聽事件
window.addEventListener('resize', setRemUnit)
方案三:lib-flexible 庫
lib-flexible 是淘寶團隊出品的一個移動端自適應解決方案,透過動態計算 viewport 設定 font-size 實作不同螢幕寬度下的 UI 自適應縮放。
(function flexible (window, document) {
var docEl = document.documentElement
var dpr = window.devicePixelRatio || 1
// adjust body font size
functionsetBodyFontSize () {
if (document.body) {
document.body. style.fontSize = (12 * dpr) + 'px'
}
else {
document.addEventListener('DOMContentLoaded', setBodyFontSize)
}
}
setBodyFontSize();
// set 1rem = viewWidth / 10
functionsetRemUnit () {
var rem = docEl.clientWidth / 10
docEl. style.fontSize = rem + 'px'
}
setRemUnit()
// reset rem unit on page resize
window.addEventListener('resize', setRemUnit)
window.addEventListener('pageshow', function (e) {
if (e.persisted) {
setRemUnit()
}
})
// detect 0.5px supports
if (dpr >= 2) {
var fakeBody = document.createElement('body')
var testElement = document.createElement('div')
testElement. style.border = '.5px solid transparent'
fakeBody.appendChild(testElement)
docEl.appendChild(fakeBody)
if (testElement.offsetHeight === 1) {
docEl. classList.add('hairlines')
}
docEl.removeChild(fakeBody)
}
}(window, document))
vw 適配方案
100vw 相當於整個視口的寬度 innerWidth,1vw 相當於視口寬度的 1%,將 px 轉換為 vw 即可完成適配,其實上面的 rem 就是模仿 vw 方案
vw相比於rem的優勢:
不需要去計算 html 的 font-size 大小,也不需要去給 html 設定 font-size
不會因為設定 html 的 font-size 大小,而必須再給 body 設定一個 font-size 防止繼承
因為不依賴 font-size 的尺寸,所以不用擔心某些原因的 html 的 font-size 尺寸被篡改,導致頁面尺寸混亂
vw 更加語意話,1vw 相當於 1/100 viewport 的大小
rem 事實上作為一種過渡的方案,它利用的也是 vw 的思想
px 與 vw 的單位轉換
手動換算
比如螢幕尺寸為 375px,元素大小為 150px,我們需要將 150px 轉換成對應的 vw 值:
150 / 3.75=40
less/scss 函式
@vwUnit: 3.75;
.pxToVw(@px) {
result: (@px / @vw) * 1vw
}
.box {
width: .pxToVw(100)[result];
height: .pxToVw(100)[result];
}
postcss-px-to-viewport-8-plugin
和rem一樣,在前端的工程化開發中,我們可以借助於webpack的工具來完成自動的轉化
npm install postcss-px-to-viewport-8-plugin
vs Code 外掛程式
px to vw 外掛程式,在編寫時自動轉化:
關於本文
作者: 專寫BUG
https://juejin.cn/post/7335245199109652516
結語
我是林三心
一個待過 小型toG型外包公司、大型外包公司、小公司、潛力型創業公司、大公司 的作死型前端選手;
一個偏前端的全幹工程師;
一個不正經的金塊作者;
逗比的B站up主;
不帥的小紅書博主;
喜歡打鐵的籃球菜鳥;
喜歡歷史的乏味少年;
喜歡rap的五音不全弱雞如果你想一起學習前端,一起摸魚,一起研究簡歷最佳化,一起研究面試進步,一起交流歷史音樂籃球rap,可以來俺的摸魚學習群哈哈,點這個,有7000多名前端小夥伴在等著一起學習哦 --> 摸魚沸點
廣州的兄弟可以約飯哦,或者約球~我負責打鐵,你負責進球,謝謝~