前几天我的领导“徐江”让我把一个挪动端我的项目做一下适配,最好让他在家用等离子电视也能看看成果,做不进去就给我“埋了”,在这种状况下才诞生了这篇文章~
什么是挪动端适配
挪动端适配是指在不同尺寸的挪动端设施上,页面能绝对达到正当的显示或者放弃对立的等比缩放成果挪动端适配的两个概念自适应:依据不同的设施屏幕大小来主动调整尺寸、大小响应式:会随着屏幕的实时变动而主动调整,是一种自适应
而在咱们日常开发中自适应布局在 pc 端和挪动端利用都极为广泛,个别是针对不同端别离做自适应布局,如果要想同时兼容挪动端和 pc 端,尤其是等离子电视这样的大屏幕,那么最好还是应用响应式布局~
挪动端适配 - 视口(viewport)
在一个浏览器中,咱们能够看到的区域就是视口(viewport), 咱们在 css 中应用的 fixed 定位就是绝对于视口进行定位的。
在 pc 端的页面中,咱们不须要对视口进行辨别,因为咱们的布局视口和视觉视口都是同一个。
而在挪动端是不太一样的,因为咱们的挪动端的网页往往很小,有可能咱们心愿一个大的网页在挪动端上也能够残缺的显示,所以在默认状况下,布局视口是大于视觉视口的。
<style>
.box {
width: 100px;
height: 100px;
background-color: orange;
}
</style>
<body>
<div class="box"></div>
</body>
pc 端展现成果
挪动端展现成果
从上图能够看出在挪动端上同样是 100px 的盒子,然而却没有占到屏幕的 1 / 3 左右的宽度,这是因为在大部分浏览器上,挪动端的布局视口宽度为 980px,咱们在把 pc 端的页面切换成挪动端页面时,右上角也短暂的显示了一下咱们的布局视口是 980px x 1743px。
所以在挪动端下,咱们能够将视口划分为 3 种状况:
- 布局视口(layout viewport)
- 视觉视口(visual layout)
- 现实视口(ideal layout)
这些概念的提出也是来自于 ppk,是一位世界级前端技术专家。
贴上大佬的文章链接 https://quirksmode.org/mobile…
所以咱们绝对于 980px 布局的这个视口,就称之为布局视口(layout viewport),而在手机端浏览器上,为了页面能够残缺的显示进去,会对整个页面进行放大,那么显示在可见区域的这个视口就是视觉视口(visual layout)。
然而咱们心愿设置的是 100px 就显示的是 100px,而这就须要咱们设置现实视口(ideal layout)。
// initial-scale:定义设施宽度与 viewport 大小之间的缩放比例
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
挪动端适配计划
- 百分比设置
- rem 单位 + 动静 html 的 font-size
- flex 的弹性布局
- vw 单位
在咱们挪动端适配计划中百分比设置是极少应用的,因为绝对的参照物可能是不同的,所以百分比往往很难对立,所以咱们经常应用的都是前面 3 种计划。
rem 单位 + 动静 html 的 font-size
rem 单位是绝对于 html 元素的 font-size 来设置的,所以咱们只须要思考 2 个问题,第一是针对不同的屏幕,能够动静的设置 html 不同的 font-size,第二是将原来的尺寸单位都转换为 rem 即可。
talk is cheap, show me the code
/*
* 计划 1: 媒体查问
* 毛病:须要针对不同的屏幕编写大量的媒体查问,且如果动静的批改尺寸,不会实时的进行更新
*/
<style>
@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;}
}
.box {
width: 5rem;
height: 5rem;
background-color: orange;
}
</style>
<body>
<div class="box"></div>
</body>
/*
* 计划 2: 编写 js 动静设置 font-size
*/
<script>
const htmlEl = document.documentElement;
function setRem() {
const htmlWidth = htmlEl.clientWidth;
const htmlFontSize = htmlWidth / 10;
htmlEl.style.fontSize = htmlFontSize + "px";
}
// 第一次不触发,须要被动调用
setRem();
window.addEventListener("resize", setRem);
</script>
<style>
.box {
width: 5rem;
height: 5rem;
background-color: orange;
}
</style>
<body>
<div class="box"></div>
</body>
然而写起来感觉还是好麻烦,如果能够的话我心愿白嫖 -0v0-
所以我抉择 postcss-pxtorem,vscode 中也能够下载到相干插件哦,一鱼多吃,😁
vw 单位
/*
* 计划 1: 手动换算
*/
<style>
/** 设置给 375 的设计稿 */
/** 1vw = 3.75px */
.box {
width: 26.667vw;
height: 26.667vw;
background-color: orange;
}
</style>
/*
* 计划 2:less/scss 函数
*/
@vwUnit: 3.75;
.pxToVw(@px) {result: (@px / @vwUnit) * 1vw;
}
.box {width: .pxToVw(100) [result];
height: .pxToVw(100) [result];
background-color: orange;
}
当然白嫖党永不言输,我抉择 postcss-px-to-viewport,贴一下我的配置文件~
module.exports = {
plugins: {
"postcss-px-to-viewport": {
unitToConvert: "px", // 须要转换的单位,默认为 "px"
viewportWidth: 750, // 视窗的宽度,对应设计稿的宽度
viewportUnit: "vw", // 指定须要转换成的视窗单位,倡议应用 vw,兼容性当初曾经比拟好了
fontViewportUnit: "vw", // 字体应用的视口单位
// viewportWidth: 1599.96, // 视窗的宽度,对应设计稿的宽度
// viewportUnit: 'vw', // 指定须要转换成的视窗单位,倡议应用 vw
// fontViewportUnit: 'vw', // 字体应用的视口单位
unitPrecision: 8, // 指定 `px` 转换为视窗单位值的小数后 x 位数
// viewportHeight: 1334, // 视窗的高度,失常不须要配置
propList: ["*"], // 能转化为 rem 的属性列表
selectorBlackList: [], // 指定不转换为视窗单位的类,能够自定义,能够有限增加, 倡议定义一至两个通用的类名
minPixelValue: 1, // 小于或等于 `1px` 不转换为视窗单位,你也能够设置为你想要的值
mediaQuery: false, // 容许在媒体查问中转换
replace: true, // 是否间接更换属性值,而不增加备用属性
// exclude: [], // 疏忽某些文件夹下的文件或特定文件,例如 'node_modules' 下的文件
landscape: false, // 是否增加依据 landscapeWidth 生成的媒体查问条件 @media (orientation: landscape)
landscapeUnit: "rem", // 横屏时应用的单位
landscapeWidth: 1134 // 横屏时应用的视口宽度
}
}
};
rem 单位和 vw 单位的区别
rem 事实上是作为一个过渡计划,它利用的也是 vw 的思维,并且随着前端的倒退,vw 的兼容性曾经越来越好了,能够说具备了 rem 的所有劣势。
然而咱们假想一个这样的场景,咱们心愿网页在达到 800px 的时候页面布局不须要持续扩充了,这个时候如果咱们采纳的是 rem 布局,咱们能够应用媒体查问设置 max-width,而 vw 则始终是以视口为单位,天然不容易解决这样的场景。
当然,vw 相比于 rem,存在以下劣势:
- 不须要计算 font-size 大小
- 不存在 font-size 继承的问题
- 不存在因为某些起因篡改了 font-size 导致页面尺寸凌乱的问题
- vw 更加的语义化
- 具备 rem 的所有长处
所以在开发中也更举荐大家应用 vw 单位进行适配。